123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- include "primitives.alh"
- include "conformance_scd.alh"
- include "library.alh"
- include "io.alh"
- include "modelling.alh"
- include "utils.alh"
- include "object_operations.alh"
- Element while_stack = ?
- Element variable_map = ?
- Element function construct_function_list(list : Element):
- String command
- Element result
- String main_function
- Boolean continue
- String prev_element
- String first_element
- Element model
- model = instantiate_model(import_node("models/ActionLanguage"))
- list = list_reverse(list)
- // Initialize variables
- prev_element = read_root()
- main_function = read_root()
- // Clear global variables
- while_stack = list_create()
- variable_map = dict_create()
- continue = True
- while (continue):
- command = list_pop_final(list)
- if (command == "global"):
- result = construct_global(model, list)
- elif (command == "funcdef"):
- result = construct_funcdef(model, list, False)
- elif (command == "mutable_funcdef"):
- result = construct_funcdef(model, list, True)
- else:
- log("ERROR (1): did not understand command " + cast_value(command))
- output("ERROR: compiled code not understood: " + cast_value(command))
- return read_root()!
- continue = list_pop_final(list)
- if (element_neq(prev_element, read_root())):
- create_al_link(model, "Statement_next", prev_element, result["start"], "next")
- else:
- first_element = result["start"]
- if (bool_and(element_eq(main_function, read_root()), command != "global")):
- // In case no main function is defined, it is the first defined function
- // This is mostly there to ensure backwards compatibility
- main_function = result["instruction"]
- prev_element = result["end"]
- if (value_eq(result["name"], "main")):
- // It was the function that we want to call
- main_function = result["instruction"]
- if (element_eq(main_function, read_root())):
- log("ERROR (2): no main function found")
- output("ERROR: no main function found")
- return read_root()!
- // Overwrite the main function with our declaration function
- prev_element = set_pop(allAssociationDestinations(model, main_function, "funcdef_body"))
- model_delete_element(model, set_pop(allOutgoingAssociationInstances(model, main_function, "funcdef_body")))
- create_al_link(model, "funcdef_body", main_function, first_element, "body")
- create_al_link(model, "Statement_next", result["end"], prev_element, "next")
- instantiate_link(model, "initial_funcdef", "", instantiate_node(model, "Initial", ""), main_function)
- return model!
- Void function create_al_link(model : Element, linktype : String, source : String, target : String, dictname : String):
- instantiate_attribute(model, instantiate_link(model, linktype, "", source, target), "name", dictname)
- return!
- String function construct_global(model : Element, list : Element):
- String this_element
- String declared_element
- String op
- this_element = instantiate_value(model, "global", "", create_value(!global))
- declared_element = instantiate_value(model, "String", "", create_value(list_pop_final(list)))
- create_al_link(model, "global_var", this_element, declared_element, "var")
- op = list_pop_final(list)
- if (op != "none"):
- // Defines
- String assign
- String resolve
- String value
- assign = instantiate_value(model, "assign", "", create_value(!assign))
- create_al_link(model, "Statement_next", this_element, assign, "next")
- resolve = instantiate_value(model, "resolve", "", create_value(!resolve))
- create_al_link(model, "assign_var", assign, resolve, "var")
- create_al_link(model, "resolve_var", resolve, declared_element, "var")
- if (op == "deref"):
- value = construct_deref(model, list)
- elif (op == "empty"):
- value = instantiate_value(model, "call", "", create_value(!call))
- String res
- String acc
- res = instantiate_value(model, "resolve", "", create_value(!resolve))
- acc = instantiate_value(model, "access", "", create_value(!access))
- create_al_link(model, "call_func", value, acc, "func")
- create_al_link(model, "access_var", acc, res, "var")
- create_al_link(model, "resolve_var", res, instantiate_value(model, "String", "", "create_node"), "var")
- elif (op == "const"):
- value = instantiate_value(model, "constant", "", create_value(!constant))
- create_al_link(model, "constant_node", value, instantiate_value(model, "Element", "", list_pop_final(list)), "node")
- create_al_link(model, "assign_value", assign, value, "value")
- Element result
- result = dict_create()
- dict_add_fast(result, "name", "")
- dict_add_fast(result, "instruction", this_element)
- dict_add_fast(result, "start", this_element)
- dict_add_fast(result, "end", assign)
- return result!
- else:
- Element result
- result = dict_create()
- dict_add_fast(result, "name", "")
- dict_add_fast(result, "instruction", this_element)
- dict_add_fast(result, "start", this_element)
- dict_add_fast(result, "end", this_element)
- return result!
- String function construct_funcdef(model : Element, list : Element, mutable : Boolean):
- String assign
- String resolve
- String constant
- String formal
- String func
- String params
- String declare
- String name
- declare = instantiate_value(model, "global", "", create_value(!global))
- assign = instantiate_value(model, "assign", "", create_value(!assign))
- resolve = instantiate_value(model, "resolve", "", create_value(!resolve))
- constant = instantiate_value(model, "constant", "", create_value(!constant))
- name = list_pop_final(list)
- if (dict_in(variable_map, name)):
- formal = dict_read(variable_map, name)
- else:
- formal = instantiate_value(model, "String", "", name)
- func = instantiate_node(model, "funcdef", "")
- params = instantiate_node(model, "param_dict", "")
- create_al_link(model, "global_var", declare, formal, "var")
- create_al_link(model, "Statement_next", declare, assign, "next")
- create_al_link(model, "assign_var", assign, resolve, "var")
- create_al_link(model, "assign_value", assign, constant, "value")
- create_al_link(model, "resolve_var", resolve, formal, "var")
- create_al_link(model, "constant_node", constant, func, "node")
- create_al_link(model, "funcdef_params", func, params, "params")
- if (mutable):
- create_al_link(model, "funcdef_mutable", func, instantiate_node(model, "Element", ""), "mutable")
- Integer nrParams
- nrParams = list_pop_final(list)
- Integer counter
- counter = 0
- Element param
- String arg_names_decl
- arg_names_decl = "abcdefghijklmnopqrstuvwxyz"
- while (counter < nrParams):
- param = instantiate_node(model, "Element", "")
- create_al_link(model, "param_dict_link", params, param, string_get(arg_names_decl, counter))
- dict_add_fast(variable_map, list_pop_final(list), param)
- // Output each parameter in turn
- counter = counter + 1
- // Now add the body
- create_al_link(model, "funcdef_body", func, construct_unknown(model, list), "body")
- Element result
- result = dict_create()
- dict_add_fast(result, "name", name)
- dict_add_fast(result, "instruction", func)
- dict_add_fast(result, "start", declare)
- dict_add_fast(result, "end", assign)
- return result!
- Element function construct_unknown(model : Element, list : Element):
- String elem
- Element new_model
- Element new_model_model
- elem = list_pop_final(list)
- if (elem == "if"):
- return construct_if(model, list)!
- elif (elem == "while"):
- return construct_while(model, list)!
- elif (elem == "access"):
- return construct_access(model, list)!
- elif (elem == "resolve"):
- return construct_resolve(model, list)!
- elif (elem == "assign"):
- return construct_assign(model, list)!
- elif (elem == "call"):
- return construct_call(model, list)!
- elif (elem == "return"):
- return construct_return(model, list)!
- elif (elem == "const"):
- return construct_const(model, list)!
- elif (elem == "declare"):
- return construct_declare(model, list)!
- elif (elem == "output"):
- return construct_output(model, list)!
- elif (elem == "input"):
- return construct_input(model, list)!
- elif (elem == "deref"):
- return construct_deref(model, list)!
- elif (elem == "break"):
- return construct_break(model, list)!
- elif (elem == "continue"):
- return construct_continue(model, list)!
- else:
- log("ERROR (2): did not understand command " + cast_value(elem))
- output("ERROR: compiled code not understood: " + cast_value(elem))
- return read_root()!
- String function construct_if(model : Element, list : Element):
- String this_element
- this_element = instantiate_value(model, "if", "", create_value(!if))
- create_al_link(model, "if_cond", this_element, construct_unknown(model, list), "cond")
- create_al_link(model, "if_then", this_element, construct_unknown(model, list), "then")
- if (list_pop_final(list)):
- create_al_link(model, "if_else", this_element, construct_unknown(model, list), "else")
- if (list_pop_final(list)):
- create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
- return this_element!
- String function construct_while(model : Element, list : Element):
- String this_element
- this_element = instantiate_value(model, "while", "", create_value(!while))
- create_al_link(model, "while_cond", this_element, construct_unknown(model, list), "cond")
- list_append(while_stack, this_element)
- create_al_link(model, "while_body", this_element, construct_unknown(model, list), "body")
- list_delete(while_stack, list_len(while_stack) - 1)
- if (list_pop_final(list)):
- create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
- return this_element!
- String function construct_access(model : Element, list : Element):
- String this_element
- this_element = instantiate_value(model, "access", "", create_value(!access))
- create_al_link(model, "access_var", this_element, construct_unknown(model, list), "var")
- return this_element!
- String function construct_resolve(model : Element, list : Element):
- String this_element
- Element linked_element
- String name
- this_element = instantiate_value(model, "resolve", "", create_value(!resolve))
- name = list_pop_final(list)
- // TODO might have to check if this is to be added
- if dict_in(variable_map, name):
- linked_element = variable_map[name]
- else:
- linked_element = instantiate_value(model, "String", "", name)
- create_al_link(model, "resolve_var", this_element, linked_element, "var")
- return this_element!
- String function construct_assign(model : Element, list : Element):
- String this_element
- this_element = instantiate_value(model, "assign", "", create_value(!assign))
- create_al_link(model, "assign_var", this_element, construct_unknown(model, list), "var")
- create_al_link(model, "assign_value", this_element, construct_unknown(model, list), "value")
- if (list_pop_final(list)):
- create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
- return this_element!
- String function construct_call(model : Element, list : Element):
- String this_element
- this_element = instantiate_value(model, "call", "", create_value(!call))
- create_al_link(model, "call_func", this_element, construct_unknown(model, list), "func")
- Integer nrParams
- nrParams = list_pop_final(list)
- Integer counter
- counter = 0
- Element param
- Element prev_param
- String arg_names_call
- arg_names_call = "abcdefghijklmnopqrstuvwxyz"
- while (counter < nrParams):
- param = instantiate_node(model, "param", "")
- create_al_link(model, "param_name", param, instantiate_value(model, "String", "", string_get(arg_names_call, counter)), "name")
- create_al_link(model, "param_value", param, construct_unknown(model, list), "value")
- if (counter == 0):
- create_al_link(model, "call_params", this_element, param, "params")
- else:
- create_al_link(model, "param_next_param", prev_param, param, "next_param")
- prev_param = param
- counter = counter + 1
- if (nrParams > 0):
- create_al_link(model, "call_last_param", this_element, prev_param, "last_param")
- if (list_pop_final(list)):
- create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
- return this_element!
- String function construct_return(model : Element, list : Element):
- if (list_pop_final(list)):
- String this_element
- this_element = instantiate_value(model, "return", "", create_value(!return))
- create_al_link(model, "return_value", this_element, construct_unknown(model, list), "value")
- return this_element!
- else:
- return instantiate_value(model, "return", "", create_value(!return))!
- String function construct_const(model : Element, list : Element):
- String this_element
- this_element = instantiate_value(model, "constant", "", create_value(!constant))
- create_al_link(model, "constant_node", this_element, instantiate_value(model, "Element", "", list_pop_final(list)), "node")
- return this_element!
- String function construct_declare(model : Element, list : Element):
- String this_element
- Element declared_element
- String name
- this_element = instantiate_value(model, "declare", "", create_value(!declare))
- declared_element = instantiate_node(model, "Element", "")
- create_al_link(model, "declare_var", this_element, declared_element, "var")
- name = list_pop_final(list)
- dict_add_fast(variable_map, name, declared_element)
- // Assign value
- String op
- op = list_pop_final(list)
- if (op != "none"):
- String assign
- String resolve
- String value
- assign = instantiate_value(model, "assign", "", create_value(!assign))
- create_al_link(model, "Statement_next", this_element, assign, "next")
- resolve = instantiate_value(model, "resolve", "", create_value(!resolve))
- create_al_link(model, "assign_var", assign, resolve, "var")
- create_al_link(model, "resolve_var", resolve, declared_element, "var")
- if (op == "deref"):
- value = construct_deref(model, list)
- elif (op == "empty"):
- value = instantiate_value(model, "call", "", create_value(!call))
- Element res
- Element acc
- res = instantiate_value(model, "resolve", "", create_value(!resolve))
- acc = instantiate_value(model, "access", "", create_value(!access))
- create_al_link(model, "call_func", value, acc, "func")
- create_al_link(model, "access_var", acc, res, "var")
- create_al_link(model, "resolve_var", res, instantiate_value(model, "String", "", "create_node"), "var")
- elif (op == "const"):
- value = instantiate_value(model, "constant", "", create_value(!constant))
- create_al_link(model, "constant_node", value, instantiate_value(model, "Element", "", list_pop_final(list)), "node")
- create_al_link(model, "assign_value", assign, value, "value")
- if (list_pop_final(list)):
- create_al_link(model, "Statement_next", assign, construct_unknown(model, list), "next")
- else:
- if (list_pop_final(list)):
- create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
- return this_element!
- String function construct_input(model : Element, list : Element):
- return instantiate_value(model, "input", "", create_value(!input))!
- String function construct_output(model : Element, list : Element):
- String this_element
- this_element = instantiate_value(model, "output", "", create_value(!output))
- create_al_link(model, "output_value", this_element, construct_unknown(model, list), "value")
- if (list_pop_final(list)):
- create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
- return this_element!
- String function construct_deref(model : Element, list : Element):
- String this_element
- this_element = instantiate_value(model, "constant", "", create_value(!constant))
- String val
- val = list_pop_final(list)
- create_al_link(model, "constant_node", this_element, reuse_element(model, "Element", "", import_node(val)), "node")
- return this_element!
- String function construct_break(model : Element, list : Element):
- String this_element
- this_element = instantiate_value(model, "break", "", create_value(!break))
- create_al_link(model, "break_while", this_element, while_stack[list_len(while_stack) - 1], "while")
- return this_element!
- String function construct_continue(model : Element, list : Element):
- String this_element
- this_element = instantiate_value(model, "continue", "", create_value(!continue))
- create_al_link(model, "continue_while", this_element, while_stack[list_len(while_stack) - 1], "while")
- return this_element!
|