To assimilate the material in parsed non-code splats.
void CodeGen::Assimilate::create_pipeline_stage(void) { CodeGen::Stage::new(I"assimilate", CodeGen::Assimilate::run_pipeline_stage, NO_STAGE_ARG, FALSE); } int current_assimilation_pass = 0; int no_assimilated_actions = 0; int no_assimilated_commands = 0; int no_assimilated_arrays = 0; int trace_AME = TRUE; int CodeGen::Assimilate::run_pipeline_stage(pipeline_step *step) { inter_tree *I = step->repository; ++current_assimilation_pass; no_assimilated_actions = 0; no_assimilated_commands = 0; no_assimilated_arrays = 0; Site::ensure_assimilation_package(I, plain_ptype_symbol); CodeGen::Assimilate::ensure(I, &verb_directive_reverse_symbol, I"VERB_DIRECTIVE_REVERSE"); CodeGen::Assimilate::ensure(I, &verb_directive_slash_symbol, I"VERB_DIRECTIVE_SLASH"); CodeGen::Assimilate::ensure(I, &verb_directive_divider_symbol, I"VERB_DIRECTIVE_DIVIDER"); CodeGen::Assimilate::ensure(I, &verb_directive_result_symbol, I"VERB_DIRECTIVE_RESULT"); CodeGen::Assimilate::ensure(I, &verb_directive_special_symbol, I"VERB_DIRECTIVE_SPECIAL"); CodeGen::Assimilate::ensure(I, &verb_directive_number_symbol, I"VERB_DIRECTIVE_NUMBER"); CodeGen::Assimilate::ensure(I, &verb_directive_noun_symbol, I"VERB_DIRECTIVE_NOUN"); CodeGen::Assimilate::ensure(I, &verb_directive_multi_symbol, I"VERB_DIRECTIVE_MULTI"); CodeGen::Assimilate::ensure(I, &verb_directive_multiinside_symbol, I"VERB_DIRECTIVE_MULTIINSIDE"); CodeGen::Assimilate::ensure(I, &verb_directive_multiheld_symbol, I"VERB_DIRECTIVE_MULTIHELD"); CodeGen::Assimilate::ensure(I, &verb_directive_held_symbol, I"VERB_DIRECTIVE_HELD"); CodeGen::Assimilate::ensure(I, &verb_directive_creature_symbol, I"VERB_DIRECTIVE_CREATURE"); CodeGen::Assimilate::ensure(I, &verb_directive_topic_symbol, I"VERB_DIRECTIVE_TOPIC"); CodeGen::Assimilate::ensure(I, &verb_directive_multiexcept_symbol, I"VERB_DIRECTIVE_MULTIEXCEPT"); if (Inter::Connectors::find_socket(I, I"self") == NULL) { inter_symbol *ss = Veneer::find_by_index(I, SELF_VSYMB, unchecked_kind_symbol); if (ss == NULL) internal_error("stuck"); Inter::Connectors::socket(I, I"self", ss); } Inter::Tree::traverse(I, CodeGen::Assimilate::visitor1, NULL, NULL, SPLAT_IST); Inter::Tree::traverse(I, CodeGen::Assimilate::visitor2, NULL, NULL, SPLAT_IST); CodeGen::Assimilate::function_bodies(I); Inter::Tree::traverse(I, CodeGen::Assimilate::visitor3, NULL, NULL, SPLAT_IST); return TRUE; } void CodeGen::Assimilate::ensure(inter_tree *I, inter_symbol **S, text_stream *identifier) { if (*S == NULL) *S = Inter::Connectors::plug(I, identifier); }
inter_bookmark CodeGen::Assimilate::template_submodule(inter_tree *I, text_stream *name, inter_tree_node *P) { if (submodule_ptype_symbol) { inter_package *template_package = Site::ensure_assimilation_package(I, plain_ptype_symbol); inter_package *t_p = Inter::Packages::by_name(template_package, name); if (t_p == NULL) { inter_bookmark IBM = Inter::Bookmarks::after_this_node(I, P); t_p = CodeGen::Assimilate::new_package_named(&IBM, name, submodule_ptype_symbol); } if (t_p == NULL) internal_error("failed to define"); return Inter::Bookmarks::at_end_of_this_package(t_p); } return Inter::Bookmarks::after_this_node(I, P); } void CodeGen::Assimilate::visitor1(inter_tree *I, inter_tree_node *P, void *state) { switch (P->W.data[PLM_SPLAT_IFLD]) { case PROPERTY_PLM: if (unchecked_kind_symbol) Assimilate definition2.1; break; case ATTRIBUTE_PLM: if (truth_state_kind_symbol) Assimilate definition2.1; break; case ROUTINE_PLM: case STUB_PLM: if ((unchecked_kind_symbol) && (unchecked_function_symbol)) Assimilate routine2.2; break; } } void CodeGen::Assimilate::visitor2(inter_tree *I, inter_tree_node *P, void *state) { switch (P->W.data[PLM_SPLAT_IFLD]) { case DEFAULT_PLM: case CONSTANT_PLM: case FAKEACTION_PLM: case OBJECT_PLM: case VERB_PLM: if (unchecked_kind_symbol) Assimilate definition2.1; break; case ARRAY_PLM: if (list_of_unchecked_kind_symbol) Assimilate definition2.1; break; } } void CodeGen::Assimilate::visitor3(inter_tree *I, inter_tree_node *P, void *state) { switch (P->W.data[PLM_SPLAT_IFLD]) { case GLOBAL_PLM: if (unchecked_kind_symbol) Assimilate definition2.1; break; } }
define MAX_ASSIMILATED_ARRAY_ENTRIES 2048
Assimilate definition2.1 =
inter_t plm = P->W.data[PLM_SPLAT_IFLD]; match_results mr = Regexp::create_mr(); text_stream *identifier = NULL; text_stream *value = NULL; int proceed = FALSE; Parse text of splat for identifier and value2.1.1; if ((proceed) && (unchecked_kind_symbol)) { if ((plm == DEFAULT_PLM) && (Inter::Connectors::find_socket(I, identifier) == NULL)) plm = CONSTANT_PLM; if (plm != DEFAULT_PLM) Act on parsed constant definition2.1.2; Inter::Tree::remove_node(P); } Regexp::dispose_of(&mr);
- This code is used in §2 (five times).
§2.1.1. Parse text of splat for identifier and value2.1.1 =
text_stream *S = Inter::Node::ID_to_text(P, P->W.data[MATTER_SPLAT_IFLD]); if (plm == VERB_PLM) { if (Regexp::match(&mr, S, L" *%C+ (%c*?) *;%c*")) { identifier = I"assim_gv"; value = mr.exp[0]; proceed = TRUE; } else LOG("Stuck on this! %S\n", S); } else { if (Regexp::match(&mr, S, L" *%C+ *(%C+?)(--> *%c*?) *;%c*")) { identifier = mr.exp[0]; value = mr.exp[1]; proceed = TRUE; } else if (Regexp::match(&mr, S, L" *%C+ *(%C+?)(-> *%c*?) *;%c*")) { identifier = mr.exp[0]; value = mr.exp[1]; proceed = TRUE; } else if (Regexp::match(&mr, S, L" *%C+ (%C*?) *;%c*")) { identifier = mr.exp[0]; proceed = TRUE; } else if (Regexp::match(&mr, S, L" *%C+ (%C*) *= *(%c*?) *;%c*")) { identifier = mr.exp[0]; value = mr.exp[1]; proceed = TRUE; } else if (Regexp::match(&mr, S, L" *%C+ (%C*) (%c*?) *;%c*")) { identifier = mr.exp[0]; value = mr.exp[1]; proceed = TRUE; } else LOG("Stuck on this! %S\n", S); } if (identifier) Str::trim_all_white_space_at_end(identifier); if (plm == FAKEACTION_PLM) { text_stream *old = identifier; identifier = Str::new(); WRITE_TO(identifier, "##%S", old); } if (plm == OBJECT_PLM) value = NULL;
- This code is used in §2.1.
§2.1.2. Act on parsed constant definition2.1.2 =
inter_bookmark IBM_d = Inter::Bookmarks::after_this_node(I, P); inter_bookmark *IBM = &IBM_d; text_stream *submodule_name = NULL; text_stream *suffix = NULL; inter_symbol *subpackage_type = plain_ptype_symbol; switch (plm) { case VERB_PLM: if (command_ptype_symbol) subpackage_type = command_ptype_symbol; submodule_name = I"commands"; suffix = NULL; break; case ARRAY_PLM: submodule_name = I"arrays"; suffix = I"arr"; break; case CONSTANT_PLM: case FAKEACTION_PLM: case OBJECT_PLM: submodule_name = I"constants"; suffix = I"con"; break; case GLOBAL_PLM: submodule_name = I"variables"; suffix = I"var"; break; case ATTRIBUTE_PLM: case PROPERTY_PLM: if (property_ptype_symbol) subpackage_type = property_ptype_symbol; submodule_name = I"properties"; suffix = I"prop"; break; } if (submodule_name) { IBM_d = CodeGen::Assimilate::template_submodule(I, submodule_name, P); TEMPORARY_TEXT(subpackage_name); if (suffix) { WRITE_TO(subpackage_name, "%S_%S", identifier, suffix); } else { WRITE_TO(subpackage_name, "assim_command_%d", ++no_assimilated_commands); } Inter::Bookmarks::set_current_package(IBM, CodeGen::Assimilate::new_package_named(IBM, subpackage_name, subpackage_type)); DISCARD_TEXT(subpackage_name); } inter_symbol *con_name = CodeGen::Assimilate::make_socketed_symbol(I, identifier, Inter::Bookmarks::scope(IBM)); Inter::Symbols::annotate_i(con_name, ASSIMILATED_IANN, 1); if (plm == FAKEACTION_PLM) Inter::Symbols::annotate_i(con_name, FAKE_ACTION_IANN, 1); if (plm == OBJECT_PLM) Inter::Symbols::annotate_i(con_name, OBJECT_IANN, 1); if (con_name->equated_to) { inter_symbol *external_name = con_name->equated_to; external_name->equated_to = con_name; con_name->equated_to = NULL; } inter_t v1 = 0, v2 = 0; switch (plm) { case CONSTANT_PLM: case FAKEACTION_PLM: case OBJECT_PLM: { Assimilate a value2.1.2.2; Produce::guard(Inter::Constant::new_numerical(IBM, Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), con_name), Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), unchecked_kind_symbol), v1, v2, (inter_t) Inter::Bookmarks::baseline(IBM) + 1, NULL)); CodeGen::Assimilate::install_socket(I, con_name, identifier); break; } case GLOBAL_PLM: Assimilate a value2.1.2.2; Produce::guard(Inter::Variable::new(IBM, Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), con_name), Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), unchecked_kind_symbol), v1, v2, (inter_t) Inter::Bookmarks::baseline(IBM) + 1, NULL)); CodeGen::Assimilate::install_socket(I, con_name, identifier); break; case ATTRIBUTE_PLM: { TEMPORARY_TEXT(A); WRITE_TO(A, "P_%S", con_name->symbol_name); inter_symbol *attr_symbol = Inter::SymbolsTables::symbol_from_name(Inter::Bookmarks::scope(IBM), A); if ((attr_symbol == NULL) || (!Inter::Symbols::is_defined(attr_symbol))) { if (attr_symbol == NULL) attr_symbol = con_name; Produce::guard(Inter::Property::new(IBM, Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), attr_symbol), Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), truth_state_kind_symbol), (inter_t) Inter::Bookmarks::baseline(IBM) + 1, NULL)); Inter::Symbols::annotate_i(attr_symbol, ATTRIBUTE_IANN, 1); Inter::Symbols::annotate_i(attr_symbol, EITHER_OR_IANN, 1); Inter::Symbols::set_translate(attr_symbol, con_name->symbol_name); if (Str::ne(attr_symbol->symbol_name, con_name->symbol_name)) { inter_symbol *alias_symbol = Inter::SymbolsTables::symbol_from_name_creating(Inter::Bookmarks::scope(IBM), con_name->symbol_name); Inter::SymbolsTables::equate(alias_symbol, attr_symbol); } } else { Inter::Symbols::annotate_i(attr_symbol, ASSIMILATED_IANN, 1); if (Str::ne(attr_symbol->symbol_name, Inter::Symbols::get_translate(attr_symbol))) { inter_symbol *alias_symbol = Inter::SymbolsTables::symbol_from_name_creating(Inter::Bookmarks::scope(IBM), Inter::Symbols::get_translate(attr_symbol)); Inter::SymbolsTables::equate(alias_symbol, attr_symbol); } } CodeGen::Assimilate::install_socket(I, attr_symbol, A); CodeGen::Assimilate::install_socket(I, attr_symbol, con_name->symbol_name); if (Str::ne(attr_symbol->symbol_name, Inter::Symbols::get_translate(attr_symbol))) CodeGen::Assimilate::install_socket(I, attr_symbol, Inter::Symbols::get_translate(attr_symbol)); DISCARD_TEXT(A); break; } case PROPERTY_PLM: { Produce::guard(Inter::Property::new(IBM, Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), con_name), Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), unchecked_kind_symbol), (inter_t) Inter::Bookmarks::baseline(IBM) + 1, NULL)); CodeGen::Assimilate::install_socket(I, con_name, identifier); if (Str::eq(identifier, I"absent")) CodeGen::Assimilate::install_socket(I, con_name, I"P_absent"); break; } case VERB_PLM: case ARRAY_PLM: { inter_t annot = 0; match_results mr2 = Regexp::create_mr(); text_stream *conts = NULL; if (plm == ARRAY_PLM) { if (Regexp::match(&mr2, value, L" *--> *(%c*?) *")) conts = mr2.exp[0]; else if (Regexp::match(&mr2, value, L" *-> *(%c*?) *")) { conts = mr2.exp[0]; annot = BYTEARRAY_IANN; } else if (Regexp::match(&mr2, value, L" *table *(%c*?) *")) { conts = mr2.exp[0]; annot = TABLEARRAY_IANN; } else if (Regexp::match(&mr2, value, L" *buffer *(%c*?) *")) { conts = mr2.exp[0]; annot = BUFFERARRAY_IANN; } else { LOG("Identifier = <%S>, Value = <%S>", identifier, value); TemplateReader::error("invalid Inform 6 array declaration in the template", NULL); } } else { conts = value; annot = VERBARRAY_IANN; } if (annot != 0) Inter::Symbols::annotate_i(con_name, annot, 1); inter_t v1_pile[MAX_ASSIMILATED_ARRAY_ENTRIES]; inter_t v2_pile[MAX_ASSIMILATED_ARRAY_ENTRIES]; int no_assimilated_array_entries = 0; string_position spos = Str::start(conts); int NT = 0, next_is_action = FALSE; while (TRUE) { TEMPORARY_TEXT(value); if (next_is_action) WRITE_TO(value, "##"); Extract a token2.1.2.1; if ((next_is_action) && (action_kind_symbol)) { CodeGen::Assimilate::ensure_action(I, P, value); } next_is_action = FALSE; if (plm == ARRAY_PLM) { if (Str::eq(value, I"+")) TemplateReader::error("Inform 6 array declaration in the template using operator '+'", NULL); if (Str::eq(value, I"-")) TemplateReader::error("Inform 6 array declaration in the template using operator '-'", NULL); if (Str::eq(value, I"*")) TemplateReader::error("Inform 6 array declaration in the template using operator '*'", NULL); if (Str::eq(value, I"/")) TemplateReader::error("Inform 6 array declaration in the template using operator '/'", NULL); } if ((NT == 0) && (plm == VERB_PLM) && (Str::eq(value, I"meta"))) { Inter::Symbols::annotate_i(con_name, METAVERB_IANN, 1); } else { Assimilate a value2.1.2.2; if (Str::len(value) == 0) break; NT++; if (no_assimilated_array_entries >= MAX_ASSIMILATED_ARRAY_ENTRIES) { TemplateReader::error("excessively long Inform 6 array in the template", NULL); break; } v1_pile[no_assimilated_array_entries] = v1; v2_pile[no_assimilated_array_entries] = v2; no_assimilated_array_entries++; if ((plm == VERB_PLM) && (verb_directive_result_symbol) && (Inter::SymbolsTables::symbol_from_data_pair_and_table(v1, v2, Inter::Bookmarks::scope(IBM)) == verb_directive_result_symbol)) next_is_action = TRUE; } DISCARD_TEXT(value); } inter_tree_node *array_in_progress = Inter::Node::fill_3(IBM, CONSTANT_IST, Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), con_name), Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), list_of_unchecked_kind_symbol), CONSTANT_INDIRECT_LIST, NULL, (inter_t) Inter::Bookmarks::baseline(IBM) + 1); int pos = array_in_progress->W.extent; if (Inter::Node::extend(array_in_progress, (unsigned int) (2*no_assimilated_array_entries)) == FALSE) internal_error("can't extend frame"); for (int i=0; i<no_assimilated_array_entries; i++) { array_in_progress->W.data[pos++] = v1_pile[i]; array_in_progress->W.data[pos++] = v2_pile[i]; } Produce::guard(Inter::Defn::verify_construct(Inter::Bookmarks::package(IBM), array_in_progress)); Inter::Bookmarks::insert(IBM, array_in_progress); if (plm == ARRAY_PLM) { CodeGen::Assimilate::install_socket(I, con_name, identifier); } break; } }
- This code is used in §2.1.
§2.1.2.1. Extract a token2.1.2.1 =
int squoted = FALSE, dquoted = FALSE, bracketed = 0; while ((Str::in_range(spos)) && (Characters::is_whitespace(Str::get(spos)))) spos = Str::forward(spos); while (Str::in_range(spos)) { wchar_t c = Str::get(spos); if ((Characters::is_whitespace(c)) && (squoted == FALSE) && (dquoted == FALSE) && (bracketed == 0)) break; if ((c == '\'') && (dquoted == FALSE)) squoted = (squoted)?FALSE:TRUE; if ((c == '\"') && (squoted == FALSE)) dquoted = (dquoted)?FALSE:TRUE; if ((c == '(') && (dquoted == FALSE) && (squoted == FALSE)) bracketed++; if ((c == ')') && (dquoted == FALSE) && (squoted == FALSE)) bracketed--; PUT_TO(value, c); spos = Str::forward(spos); }
§2.1.2.2. Assimilate a value2.1.2.2 =
if (Str::len(value) > 0) { CodeGen::Assimilate::value(I, Inter::Bookmarks::package(IBM), IBM, value, &v1, &v2, (plm == VERB_PLM)?TRUE:FALSE); } else { v1 = LITERAL_IVAL; v2 = 0; }
- This code is used in §2.1.2 (three times).
text_stream *identifier = NULL, *chain = NULL, *body = NULL; match_results mr = Regexp::create_mr(); Parse the routine or stub header2.2.1; if (identifier) Act on parsed header2.2.2;
- This code is used in §2.
§2.2.1. Parse the routine or stub header2.2.1 =
text_stream *S = Inter::Node::ID_to_text(P, P->W.data[MATTER_SPLAT_IFLD]); if (P->W.data[PLM_SPLAT_IFLD] == ROUTINE_PLM) { if (Regexp::match(&mr, S, L" *%[ *(%i+) *; *(%c*)")) { identifier = mr.exp[0]; body = mr.exp[1]; } else if (Regexp::match(&mr, S, L" *%[ *(%i+) *(%c*?); *(%c*)")) { identifier = mr.exp[0]; chain = mr.exp[1]; body = mr.exp[2]; } else { TemplateReader::error("invalid Inform 6 routine declaration in the template", NULL); } } else { if (Regexp::match(&mr, S, L" *%C+ *(%i+) (%d+);%c*")) { identifier = mr.exp[0]; chain = Str::new(); int N = Str::atoi(mr.exp[1], 0); if ((N<0) || (N>15)) N = 1; for (int i=1; i<=N; i++) WRITE_TO(chain, "x%d ", i); body = Str::duplicate(I"rfalse; ];"); } else TemplateReader::error("invalid Inform 6 Stub declaration in the template", NULL); }
- This code is used in §2.2.
§2.2.2. Act on parsed header2.2.2 =
inter_bookmark IBM_d = CodeGen::Assimilate::template_submodule(I, I"functions", P); inter_bookmark *IBM = &IBM_d; inter_symbol *fnt = function_ptype_symbol; if (fnt == NULL) fnt = plain_ptype_symbol; TEMPORARY_TEXT(fname); WRITE_TO(fname, "%S_fn", identifier); inter_package *FP = CodeGen::Assimilate::new_package_named(IBM, fname, fnt); DISCARD_TEXT(fname); inter_bookmark outer_save = Inter::Bookmarks::snapshot(IBM); Inter::Bookmarks::set_current_package(IBM, FP); TEMPORARY_TEXT(bname); WRITE_TO(bname, "%S_B", identifier); inter_package *IP = CodeGen::Assimilate::new_package_named(IBM, bname, code_ptype_symbol); DISCARD_TEXT(bname); inter_bookmark inner_save = Inter::Bookmarks::snapshot(IBM); Inter::Bookmarks::set_current_package(IBM, IP); inter_bookmark block_bookmark = Inter::Bookmarks::snapshot(IBM); if (chain) { string_position spos = Str::start(chain); while (TRUE) { TEMPORARY_TEXT(value); Extract a token2.1.2.1; if (Str::len(value) == 0) break; inter_symbol *loc_name = Inter::SymbolsTables::create_with_unique_name(Inter::Packages::scope(IP), value); Inter::Symbols::local(loc_name); Produce::guard(Inter::Local::new(IBM, loc_name, unchecked_kind_symbol, 0, (inter_t) Inter::Bookmarks::baseline(IBM) + 1, NULL)); DISCARD_TEXT(value); } } Produce::guard(Inter::Code::new(IBM, (int) (inter_t) Inter::Bookmarks::baseline(IBM) + 1, NULL)); if (Str::len(body) > 0) { int L = Str::len(body) - 1; while ((L>0) && (Str::get_at(body, L) != ']')) L--; while ((L>0) && (Characters::is_whitespace(Str::get_at(body, L-1)))) L--; Str::truncate(body, L); CodeGen::Assimilate::routine_body(IBM, IP, (inter_t) Inter::Bookmarks::baseline(IBM) + 1, body, block_bookmark); } *IBM = inner_save; inter_symbol *rsymb = CodeGen::Assimilate::make_socketed_symbol(I, identifier, Inter::Bookmarks::scope(IBM)); Inter::Symbols::annotate_i(rsymb, ASSIMILATED_IANN, 1); Produce::guard(Inter::Constant::new_function(IBM, Inter::SymbolsTables::id_from_symbol(I, FP, rsymb), Inter::SymbolsTables::id_from_symbol(I, FP, unchecked_function_symbol), IP, (inter_t) Inter::Bookmarks::baseline(IBM) + 1, NULL)); *IBM = outer_save; CodeGen::Assimilate::install_socket(I, rsymb, rsymb->symbol_name); Inter::Tree::remove_node(P);
- This code is used in §2.2.
inter_package *CodeGen::Assimilate::new_package_named(inter_bookmark *IBM, text_stream *name, inter_symbol *ptype) { inter_package *P = NULL; Produce::guard(Inter::Package::new_package_named(IBM, name, TRUE, ptype, (inter_t) Inter::Bookmarks::baseline(IBM) + 1, NULL, &P)); return P; } void CodeGen::Assimilate::install_socket(inter_tree *I, inter_symbol *con_name, text_stream *aka_text) { inter_symbol *socket = Inter::Connectors::find_socket(I, aka_text); if (socket == NULL) Inter::Connectors::socket(I, aka_text, con_name); } inter_symbol *CodeGen::Assimilate::make_socketed_symbol(inter_tree *I, text_stream *identifier, inter_symbols_table *into_scope) { inter_symbol *new_symbol = Inter::SymbolsTables::create_with_unique_name(into_scope, identifier); CodeGen::Assimilate::install_socket(I, new_symbol, identifier); return new_symbol; }
void CodeGen::Assimilate::ensure_action(inter_tree *I, inter_tree_node *P, text_stream *value) { if (Inter::Connectors::find_socket(I, value) == NULL) { inter_bookmark IBM_d = CodeGen::Assimilate::template_submodule(I, I"actions", P); inter_bookmark *IBM = &IBM_d; inter_symbol *ptype = action_ptype_symbol; if (ptype == NULL) ptype = plain_ptype_symbol; TEMPORARY_TEXT(an); WRITE_TO(an, "assim_action_%d", ++no_assimilated_actions); Inter::Bookmarks::set_current_package(IBM, CodeGen::Assimilate::new_package_named(IBM, an, ptype)); DISCARD_TEXT(an); inter_symbol *asymb = CodeGen::Assimilate::make_socketed_symbol(I, value, Inter::Bookmarks::scope(IBM)); TEMPORARY_TEXT(unsharped); WRITE_TO(unsharped, "%SSub", value); Str::delete_first_character(unsharped); Str::delete_first_character(unsharped); inter_symbol *txsymb = Inter::Connectors::find_socket(I, unsharped); inter_symbol *xsymb = Inter::SymbolsTables::create_with_unique_name(Inter::Bookmarks::scope(IBM), unsharped); if (txsymb) Inter::SymbolsTables::equate(xsymb, txsymb); DISCARD_TEXT(unsharped); Produce::guard(Inter::Constant::new_numerical(IBM, Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), asymb), Inter::SymbolsTables::id_from_symbol(I, Inter::Bookmarks::package(IBM), action_kind_symbol), LITERAL_IVAL, 10000, (inter_t) Inter::Bookmarks::baseline(IBM) + 1, NULL)); Inter::Symbols::annotate_i(asymb, ACTION_IANN, 1); } }
void CodeGen::Assimilate::value(inter_tree *I, inter_package *pack, inter_bookmark *IBM, text_stream *S, inter_t *val1, inter_t *val2, int Verbal) { int sign = 1, base = 10, from = 0, to = Str::len(S)-1, bad = FALSE; if ((Str::get_at(S, from) == '\'') && (Str::get_at(S, to) == '\'')) { from++; to--; TEMPORARY_TEXT(dw); LOOP_THROUGH_TEXT(pos, S) { if (pos.index < from) continue; if (pos.index > to) continue; int c = Str::get(pos); PUT_TO(dw, c); } inter_t ID = Inter::Warehouse::create_text(Inter::Tree::warehouse(I), pack); text_stream *glob_storage = Inter::Warehouse::get_text(Inter::Tree::warehouse(I), ID); Str::copy(glob_storage, dw); *val1 = DWORD_IVAL; *val2 = ID; DISCARD_TEXT(dw); return; } if ((Str::get_at(S, from) == '"') && (Str::get_at(S, to) == '"')) { from++; to--; TEMPORARY_TEXT(dw); LOOP_THROUGH_TEXT(pos, S) { if (pos.index < from) continue; if (pos.index > to) continue; int c = Str::get(pos); PUT_TO(dw, c); } inter_t ID = Inter::Warehouse::create_text(Inter::Tree::warehouse(I), pack); text_stream *glob_storage = Inter::Warehouse::get_text(Inter::Tree::warehouse(I), ID); Str::copy(glob_storage, dw); *val1 = LITERAL_TEXT_IVAL; *val2 = ID; DISCARD_TEXT(dw); return; } if ((Str::get_at(S, from) == '(') && (Str::get_at(S, to) == ')')) { from++; to--; } while (Characters::is_whitespace(Str::get_at(S, from))) from++; while (Characters::is_whitespace(Str::get_at(S, to))) to--; if (Str::get_at(S, from) == '-') { sign = -1; from++; } else if (Str::get_at(S, from) == '$') { from++; base = 16; if (Str::get_at(S, from) == '$') { from++; base = 2; } } long long int N = 0; LOOP_THROUGH_TEXT(pos, S) { if (pos.index < from) continue; if (pos.index > to) continue; int c = Str::get(pos), d = 0; if ((c >= 'a') && (c <= 'z')) d = c-'a'+10; else if ((c >= 'A') && (c <= 'Z')) d = c-'A'+10; else if ((c >= '0') && (c <= '9')) d = c-'0'; else { bad = TRUE; break; } if (d > base) { bad = TRUE; break; } N = base*N + (long long int) d; if (pos.index > 34) { bad = TRUE; break; } } if (bad == FALSE) { N = sign*N; *val1 = LITERAL_IVAL; *val2 = (inter_t) N; return; } if (Str::eq(S, I"true")) { *val1 = LITERAL_IVAL; *val2 = 1; return; } if (Str::eq(S, I"false")) { *val1 = LITERAL_IVAL; *val2 = 0; return; } if (Verbal) { if ((Str::eq(S, I"*")) && (verb_directive_divider_symbol)) { Inter::Symbols::to_data(I, pack, verb_directive_divider_symbol, val1, val2); return; } if ((Str::eq(S, I"->")) && (verb_directive_result_symbol)) { Inter::Symbols::to_data(I, pack, verb_directive_result_symbol, val1, val2); return; } if ((Str::eq(S, I"reverse")) && (verb_directive_reverse_symbol)) { Inter::Symbols::to_data(I, pack, verb_directive_reverse_symbol, val1, val2); return; } if ((Str::eq(S, I"/")) && (verb_directive_slash_symbol)) { Inter::Symbols::to_data(I, pack, verb_directive_slash_symbol, val1, val2); return; } if ((Str::eq(S, I"special")) && (verb_directive_special_symbol)) { Inter::Symbols::to_data(I, pack, verb_directive_special_symbol, val1, val2); return; } if ((Str::eq(S, I"number")) && (verb_directive_number_symbol)) { Inter::Symbols::to_data(I, pack, verb_directive_number_symbol, val1, val2); return; } match_results mr = Regexp::create_mr(); if (Regexp::match(&mr, S, L"scope=(%i+)")) { inter_symbol *symb = Inter::Connectors::find_socket(I, mr.exp[0]); while ((symb) && (symb->equated_to)) symb = symb->equated_to; if (symb) { if (Inter::Symbols::read_annotation(symb, SCOPE_FILTER_IANN) != 1) Inter::Symbols::annotate_i(symb, SCOPE_FILTER_IANN, 1); Inter::Symbols::to_data(I, pack, symb, val1, val2); return; } } if (Regexp::match(&mr, S, L"noun=(%i+)")) { inter_symbol *symb = Inter::Connectors::find_socket(I, mr.exp[0]); while ((symb) && (symb->equated_to)) symb = symb->equated_to; if (symb) { if (Inter::Symbols::read_annotation(symb, NOUN_FILTER_IANN) != 1) Inter::Symbols::annotate_i(symb, NOUN_FILTER_IANN, 1); Inter::Symbols::to_data(I, pack, symb, val1, val2); return; } } } inter_symbol *symb = Inter::Connectors::find_socket(I, S); if (symb) { Inter::Symbols::to_data(I, pack, symb, val1, val2); return; } inter_schema *sch = InterSchemas::from_text(S, FALSE, 0, NULL); inter_symbol *mcc_name = CodeGen::Assimilate::compute_constant(I, pack, IBM, sch); Inter::Symbols::to_data(I, pack, mcc_name, val1, val2); } inter_symbol *CodeGen::Assimilate::compute_constant(inter_tree *I, inter_package *pack, inter_bookmark *IBM, inter_schema *sch) { inter_symbol *try = CodeGen::Assimilate::compute_constant_r(I, pack, IBM, sch->node_tree); if (try) return try; InterSchemas::log(DL, sch); LOG("Forced to glob: %S\n", sch->converted_from); WRITE_TO(STDERR, "Forced to glob: %S\n", sch->converted_from); internal_error("Reduced to glob in assimilation"); inter_t ID = Inter::Warehouse::create_text(Inter::Tree::warehouse(I), pack); text_stream *glob_storage = Inter::Warehouse::get_text(Inter::Tree::warehouse(I), ID); Str::copy(glob_storage, sch->converted_from); inter_symbol *mcc_name = CodeGen::Assimilate::computed_constant_symbol(pack); Produce::guard(Inter::Constant::new_numerical(IBM, Inter::SymbolsTables::id_from_symbol(I, pack, mcc_name), Inter::SymbolsTables::id_from_symbol(I, pack, unchecked_kind_symbol), GLOB_IVAL, ID, (inter_t) Inter::Bookmarks::baseline(IBM) + 1, NULL)); return mcc_name; } inter_symbol *CodeGen::Assimilate::compute_constant_r(inter_tree *I, inter_package *pack, inter_bookmark *IBM, inter_schema_node *isn) { if (isn->isn_type == SUBEXPRESSION_ISNT) return CodeGen::Assimilate::compute_constant_r(I, pack, IBM, isn->child_node); if (isn->isn_type == OPERATION_ISNT) { inter_t op = 0; if (isn->isn_clarifier == PLUS_BIP) op = CONSTANT_SUM_LIST; else if (isn->isn_clarifier == TIMES_BIP) op = CONSTANT_PRODUCT_LIST; else if (isn->isn_clarifier == MINUS_BIP) op = CONSTANT_DIFFERENCE_LIST; else if (isn->isn_clarifier == DIVIDE_BIP) op = CONSTANT_QUOTIENT_LIST; else if (isn->isn_clarifier == UNARYMINUS_BIP) return CodeGen::Assimilate::compute_constant_unary_operation(I, pack, IBM, isn->child_node); else return NULL; inter_symbol *i1 = CodeGen::Assimilate::compute_constant_r(I, pack, IBM, isn->child_node); inter_symbol *i2 = CodeGen::Assimilate::compute_constant_r(I, pack, IBM, isn->child_node->next_node); if ((i1 == NULL) || (i2 == NULL)) return NULL; return CodeGen::Assimilate::compute_constant_binary_operation(op, I, pack, IBM, i1, i2); } if (isn->isn_type == EXPRESSION_ISNT) { inter_schema_token *t = isn->expression_tokens; if (t->next) { if (t->next->next) return NULL; inter_symbol *i1 = CodeGen::Assimilate::compute_constant_eval(I, pack, IBM, t); inter_symbol *i2 = CodeGen::Assimilate::compute_constant_eval(I, pack, IBM, t->next); if ((i1 == NULL) || (i2 == NULL)) return NULL; return CodeGen::Assimilate::compute_constant_binary_operation(CONSTANT_SUM_LIST, I, pack, IBM, i1, i2); } return CodeGen::Assimilate::compute_constant_eval(I, pack, IBM, t); } return NULL; } inter_symbol *CodeGen::Assimilate::compute_constant_eval(inter_tree *I, inter_package *pack, inter_bookmark *IBM, inter_schema_token *t) { inter_t v1 = UNDEF_IVAL, v2 = 0; switch (t->ist_type) { case IDENTIFIER_ISTT: { inter_symbol *symb = Inter::Connectors::find_socket(I, t->material); if (symb) return symb; return Inter::Connectors::plug(I, t->material); } case NUMBER_ISTT: case BIN_NUMBER_ISTT: case HEX_NUMBER_ISTT: if (t->constant_number >= 0) { v1 = LITERAL_IVAL; v2 = (inter_t) t->constant_number; } else if (Inter::Types::read_I6_decimal(t->material, &v1, &v2) == FALSE) internal_error("bad number"); break; } if (v1 == UNDEF_IVAL) return NULL; inter_symbol *mcc_name = CodeGen::Assimilate::computed_constant_symbol(pack); Produce::guard(Inter::Constant::new_numerical(IBM, Inter::SymbolsTables::id_from_symbol(I, pack, mcc_name), Inter::SymbolsTables::id_from_symbol(I, pack, unchecked_kind_symbol), v1, v2, (inter_t) Inter::Bookmarks::baseline(IBM) + 1, NULL)); return mcc_name; } inter_symbol *CodeGen::Assimilate::compute_constant_unary_operation(inter_tree *I, inter_package *pack, inter_bookmark *IBM, inter_schema_node *operand1) { inter_symbol *i1 = CodeGen::Assimilate::compute_constant_r(I, pack, IBM, operand1); if (i1 == NULL) return NULL; inter_symbol *mcc_name = CodeGen::Assimilate::computed_constant_symbol(pack); inter_tree_node *array_in_progress = Inter::Node::fill_3(IBM, CONSTANT_IST, Inter::SymbolsTables::id_from_IRS_and_symbol(IBM, mcc_name), Inter::SymbolsTables::id_from_symbol(I, pack, unchecked_kind_symbol), CONSTANT_DIFFERENCE_LIST, NULL, (inter_t) Inter::Bookmarks::baseline(IBM) + 1); int pos = array_in_progress->W.extent; if (Inter::Node::extend(array_in_progress, 4) == FALSE) internal_error("can't extend frame"); array_in_progress->W.data[pos] = LITERAL_IVAL; array_in_progress->W.data[pos+1] = 0; Inter::Symbols::to_data(I, pack, i1, &(array_in_progress->W.data[pos+2]), &(array_in_progress->W.data[pos+3])); Produce::guard(Inter::Defn::verify_construct(Inter::Bookmarks::package(IBM), array_in_progress)); Inter::Bookmarks::insert(IBM, array_in_progress); return mcc_name; } inter_symbol *CodeGen::Assimilate::compute_constant_binary_operation(inter_t op, inter_tree *I, inter_package *pack, inter_bookmark *IBM, inter_symbol *i1, inter_symbol *i2) { inter_symbol *mcc_name = CodeGen::Assimilate::computed_constant_symbol(pack); inter_tree_node *array_in_progress = Inter::Node::fill_3(IBM, CONSTANT_IST, Inter::SymbolsTables::id_from_IRS_and_symbol(IBM, mcc_name), Inter::SymbolsTables::id_from_symbol(I, pack, unchecked_kind_symbol), op, NULL, (inter_t) Inter::Bookmarks::baseline(IBM) + 1); int pos = array_in_progress->W.extent; if (Inter::Node::extend(array_in_progress, 4) == FALSE) internal_error("can't extend frame"); Inter::Symbols::to_data(I, pack, i1, &(array_in_progress->W.data[pos]), &(array_in_progress->W.data[pos+1])); Inter::Symbols::to_data(I, pack, i2, &(array_in_progress->W.data[pos+2]), &(array_in_progress->W.data[pos+3])); Produce::guard(Inter::Defn::verify_construct(Inter::Bookmarks::package(IBM), array_in_progress)); Inter::Bookmarks::insert(IBM, array_in_progress); return mcc_name; } int ccs_count = 0; inter_symbol *CodeGen::Assimilate::computed_constant_symbol(inter_package *pack) { TEMPORARY_TEXT(NN); WRITE_TO(NN, "Computed_Constant_Value_%d", ccs_count++); inter_symbol *mcc_name = Inter::SymbolsTables::symbol_from_name_creating(Inter::Packages::scope(pack), NN); Inter::Symbols::set_flag(mcc_name, MAKE_NAME_UNIQUE); DISCARD_TEXT(NN); return mcc_name; } typedef struct routine_body_request { int assimilation_pass; struct inter_bookmark position; struct inter_bookmark block_bookmark; struct package_request *enclosure; struct inter_package *block_package; int pass2_offset; struct text_stream *body; MEMORY_MANAGEMENT } routine_body_request; int rb_splat_count = 1; int CodeGen::Assimilate::routine_body(inter_bookmark *IBM, inter_package *block_package, inter_t offset, text_stream *body, inter_bookmark bb) { if (Str::is_whitespace(body)) return FALSE; routine_body_request *req = CREATE(routine_body_request); req->assimilation_pass = current_assimilation_pass; req->block_bookmark = bb; req->enclosure = Packaging::enclosure(Inter::Bookmarks::tree(IBM)); req->position = Packaging::bubble_at(IBM); req->block_package = block_package; req->pass2_offset = (int) offset - 2; req->body = Str::duplicate(body); return TRUE; } void CodeGen::Assimilate::function_bodies(inter_tree *I) { routine_body_request *req; LOOP_OVER(req, routine_body_request) if (req->assimilation_pass == current_assimilation_pass) { LOGIF(SCHEMA_COMPILATION, "=======\n\nRoutine (%S) len %d: '%S'\n\n", Inter::Packages::name(req->block_package), Str::len(req->body), req->body); inter_schema *sch = InterSchemas::from_text(req->body, FALSE, 0, NULL); if (Log::aspect_switched_on(SCHEMA_COMPILATION_DA)) { if (sch == NULL) LOG("NULL SCH\n"); else if (sch->node_tree == NULL) { LOG("Lint fail: Non-empty text but empty scheme\n"); internal_error("inter schema empty"); } else InterSchemas::log(DL, sch); } Site::set_cir(I, req->block_package); Packaging::set_state(I, &(req->position), req->enclosure); Produce::push_code_position(I, Produce::new_cip(I, &(req->position)), Inter::Bookmarks::snapshot(Packaging::at(I))); value_holster VH = Holsters::new(INTER_VOID_VHMODE); inter_symbols_table *scope1 = Inter::Packages::scope(req->block_package); inter_package *template_package = Site::assimilation_package(I); inter_symbols_table *scope2 = Inter::Packages::scope(template_package); EmitInterSchemas::emit(I, &VH, sch, NULL, TRUE, FALSE, scope1, scope2, NULL, NULL); Produce::pop_code_position(I); Site::set_cir(I, NULL); } }
- The structure routine_body_request is private to this section.