IF $(argc) < 5
    ERROR Wrong number of parameters[$(argc)]. Usage: aisc aisc_global.pa xxx.aisc outfile extern_file
ENDIF

DATA AISC { $(#FILE $(argv[2])) };
DUMPDATA DUMP/aisc_global.pa__$(argv[2]).dump
OPEN save $(argv[3])

MOVETO $(AISC/PROJECT)
CREATE $(pre) = $(OBJECT_KEY)_
CREATE $(max_key) = $(MAX_KEY)
CREATE $(max_obj) = $(MAX_OBJECT)
CREATE $(i)
CREATE $(termlist) = $10$n};$n

OUT save

MOVETO $(DATA/.)

P /* -----------------------------------------------------------------
P  * Created automagically from ../$(argv[2]) 
P  *                       and ../$(argv[4])
P  * using aisc-script '../AISC/aisc_global.pa'
P  * DO NOT EDIT THIS FILE!!!
P  * ----------------------------------------------------------------- */
--
P #include <aisc_server.h>
--

# create and clear obj and key list
FOR $(i) = 0 TO $(max_obj)
    CREATE $(obj[$(i)]) = 0,
ENDFOR
FOR $(i) = 0 TO $(max_key)
    CREATE $(key[$(i)]) = 0,
ENDFOR

# generate object names struct
FOR $(STRUCT)
    IF $(SKEY)
        IF $(obj[$(SKEYC)])
            SET $(obj[$(SKEYC)]) = "$(pre)$(SKEY)",
        ELSE
            ERROR Increase definition of MAX_OBJECT to $(SKEYC)
        ENDIF
    ENDIF
ENDFOR

P const char *aisc_object_names[] = {
GOSUB printobjlist
P $(termlist)

# generate attribute names structs
CREATE $(nummer)
CREATE $(aisc_string)
FOR $(STRUCT)
    IF $(SKEY)
        GOSUB clearkeylist
        SET $(nummer) = 0
        SET $(aisc_string) = $(pre)$(SKEY)_
        P static const char *$(pre)$(STRUCT)_attribute_names[] = {
        GOSUB make_attr_names
        GOSUB printkeylist
        P $(termlist)
    ENDIF
ENDFOR
P $n

# generate attribute names struct list
GOSUB clearobjlist
P const char *aisc_attribute_names_list[] = {
FOR $(STRUCT)
    IF $(SKEY)
        SET $(obj[$(SKEYC)]) = (const char *)$(pre)$(STRUCT)_attribute_names,
    ENDIF
ENDFOR
GOSUB printobjlist
P $(termlist)

# generate function structs
P typedef int* (*talking_function)(int *x, ...);
P typedef talking_function *talking_function_ptr;
--
FOR $(STRUCT)
    P extern talking_function aisc_talking_functions_create_$(STRUCT)[];
    P extern int *((*(aisc_talking_functions_get_$(STRUCT)[]))());
    P extern int *((*(aisc_talking_functions_find_$(STRUCT)[]))());
    P extern int *((*(aisc_talking_functions_copy_$(STRUCT)[]))());
    P extern int ((*(aisc_talking_functions_set_$(STRUCT)[]))());
    --
ENDFOR

# generate d flags
P int aisc_d_flags[] = {
GOSUB clearkeylist
FOR $(STRUCT)
    IF $(SKEY)
        SET $(i) = 0
        FOR $({/TYPE)
            IF $(TYPE) = dllh
                SET $(i) = 1
            ENDIF
        ENDFOR
        SET $(key[$(SKEYC)]) = $(i),$6// $(SKEY)
    ENDIF
ENDFOR
GOSUB printkeylist
P $(termlist)

# generate callback tables
P int *((**(aisc_talking_functions_get[]))()) = {
GOSUB print_talking_table,aisc_talking_functions_get_

P int ((**(aisc_talking_functions_set[]))()) = {
GOSUB print_talking_table,aisc_talking_functions_set_

P int *((**(aisc_talking_functions_find[]))()) = {
GOSUB print_talking_table,aisc_talking_functions_find_

P int *((**(aisc_talking_functions_copy[]))()) = {
GOSUB print_talking_table,aisc_talking_functions_copy_

P talking_function* aisc_talking_functions_create[] = {
GOSUB print_talking_table,aisc_talking_functions_create_

P aisc_destroy_callback aisc_talking_functions_delete[] = {
GOSUB print_talking_table_casted,destroy_,(aisc_destroy_callback)

# FINISH
P #undef __P
CLOSE save
EXIT

# ----------------- 
#     FUNCTIONS     

FUNCTION print_talking_table,name
    CALL print_talking_table_casted,$(name),
RETURN

FUNCTION print_talking_table_casted,name,cast
    GOSUB clearkeylist
    FOR $(STRUCT)
        IF $(SKEY)
            SET $(key[$(SKEYC)]) = $(cast)$(name)$(STRUCT),
        ENDIF
    ENDFOR
    GOSUB printkeylist
    P $(termlist)
RETURN

FUNCTION make_attr_names
    CREATE $(nr) = $(nummer)
    CREATE $(s) = $(aisc_string)
    FOR $({/TYPE)
        IF $(KEY)
            IF $(REF) ~ s
                PUSH
                SET $(nummer) = $(+ $(nr)+$(KEYC) )
                SET $(aisc_string) = $(s)$(KEY)_
                MOVETO $(/AISC/DATA/STRUCT.$(TYPE))
                GOSUB make_attr_names
                POP
            ELSEIF $(REF) ~ d
                SET $(key[$(+ $(+ $(nr)+1)+$(KEYC))])="$(s)$(KEY)CNT",
                SET $(key[$(+ $(nr)+$(KEYC))]) = "$(s)$(KEY)",
            ELSEIF $(TYPE) = dllh
                PUSH
                SET $(nummer) = $(+ 2+$(+ $(nr)+$(KEYC) ))
                SET $(aisc_string) = $(s)$(KEY)
                MOVETO $(/AISC/DATA/STRUCT.dll_header)
                GOSUB make_attr_names
                POP
                SET $(key[$(+ $(nr)+0)]) = "$(s)PREVIOUS",
                SET $(key[$(+ $(nr)+1)]) = "$(s)NEXT",
            ELSE
                SET $(key[$(+ $(nr)+$(KEYC))]) = "$(s)$(KEY)",
            ENDIF
        ENDIF
    ENDFOR
RETURN

FUNCTION clearkeylist
    FOR $(i) = 0 TO $(max_key)
        SET $(key[$(i)]) = 0,
    ENDFOR
RETURN
FUNCTION clearobjlist
    FOR $(i) = 0 TO $(max_obj)
        SET $(obj[$(i)]) = 0,
    ENDFOR
RETURN
FUNCTION printkeylist
    FOR $(i) = 0 TO $(max_key)
        P $1$(key[$(i)])
    ENDFOR
RETURN
FUNCTION printobjlist
    FOR $(i) = 0 TO $(max_obj)
        P $1$(obj[$(i)])
    ENDFOR
RETURN

