From 4b561c4bd0d6be887c6b063d6ab6c9d70ae63c46 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Fri, 11 Mar 2022 19:22:44 +0000 Subject: [PATCH] Improved variable instruction --- inform7/runtime-module/Chapter 2/Emit.w | 4 +- .../Chapter 4/The Typename Construct.w | 4 +- .../Chapter 4/The Variable Construct.w | 125 +++++++++++------- .../final-module/Chapter 2/Code Generation.w | 2 +- .../Chapter 4/Inform 6 Global Variables.w | 2 +- .../Chapter 5/C Global Variables.w | 2 +- .../Chapter 3/Compile Splats Stage.w | 12 +- 7 files changed, 93 insertions(+), 58 deletions(-) diff --git a/inform7/runtime-module/Chapter 2/Emit.w b/inform7/runtime-module/Chapter 2/Emit.w index 19e23a16e..5610c8ad3 100644 --- a/inform7/runtime-module/Chapter 2/Emit.w +++ b/inform7/runtime-module/Chapter 2/Emit.w @@ -300,8 +300,8 @@ inter_symbol *Emit::variable(inter_name *var_iname, kind *K, inter_pair val) { inter_type type = InterTypes::unchecked(); if ((K) && (K != K_value)) type = InterTypes::from_type_name(Produce::kind_to_symbol(K)); - Produce::guard(VariableInstruction::new(Emit::at(), - Emit::symbol_id(var_s), type, val, Emit::baseline(), NULL)); + Produce::guard(VariableInstruction::new(Emit::at(), var_s, type, val, + Emit::baseline(), NULL)); Packaging::exit(Emit::tree(), save); return var_s; } diff --git a/inter/bytecode-module/Chapter 4/The Typename Construct.w b/inter/bytecode-module/Chapter 4/The Typename Construct.w index 3d69e406f..0838b3f4f 100644 --- a/inter/bytecode-module/Chapter 4/The Typename Construct.w +++ b/inter/bytecode-module/Chapter 4/The Typename Construct.w @@ -2,8 +2,8 @@ Defining the typename construct. -@ - +@h Definition. +For what this does and why it is used, see //inter: Textual Inter//. = void TypenameInstruction::define_construct(void) { diff --git a/inter/bytecode-module/Chapter 4/The Variable Construct.w b/inter/bytecode-module/Chapter 4/The Variable Construct.w index 98b471037..1e34a5e1f 100644 --- a/inter/bytecode-module/Chapter 4/The Variable Construct.w +++ b/inter/bytecode-module/Chapter 4/The Variable Construct.w @@ -2,14 +2,15 @@ Defining the variable construct. -@ +@h Definition. +For what this does and why it is used, see //inter: Textual Inter//. = void VariableInstruction::define_construct(void) { inter_construct *IC = InterInstruction::create_construct(VARIABLE_IST, I"variable"); - InterInstruction::defines_symbol_in_fields(IC, DEFN_VAR_IFLD, KIND_VAR_IFLD); + InterInstruction::defines_symbol_in_fields(IC, DEFN_VAR_IFLD, TYPE_VAR_IFLD); InterInstruction::specify_syntax(IC, I"variable TOKENS = TOKENS"); - InterInstruction::fix_instruction_length_between(IC, EXTENT_VAR_IFR, EXTENT_VAR_IFR); + InterInstruction::fix_instruction_length_between(IC, 6, 6); InterInstruction::permit(IC, INSIDE_PLAIN_PACKAGE_ICUP); InterInstruction::permit(IC, CAN_HAVE_ANNOTATIONS_ICUP); METHOD_ADD(IC, CONSTRUCT_READ_MTID, VariableInstruction::read); @@ -17,60 +18,94 @@ void VariableInstruction::define_construct(void) { METHOD_ADD(IC, CONSTRUCT_WRITE_MTID, VariableInstruction::write); } -@ +@h Instructions. +In bytecode, the frame of a |propertyvalue| instruction is laid out with the two +compulsory words |ID_IFLD| and |LEVEL_IFLD|, followed by: @d DEFN_VAR_IFLD 2 -@d KIND_VAR_IFLD 3 +@d TYPE_VAR_IFLD 3 @d VAL1_VAR_IFLD 4 @d VAL2_VAR_IFLD 5 -@d EXTENT_VAR_IFR 6 - = -void VariableInstruction::read(inter_construct *IC, inter_bookmark *IBM, inter_line_parse *ilp, inter_error_location *eloc, inter_error_message **E) { - text_stream *kind_text = NULL, *name_text = ilp->mr.exp[0]; - match_results mr2 = Regexp::create_mr(); - if (Regexp::match(&mr2, name_text, L"%((%c+)%) (%c+)")) { - kind_text = mr2.exp[0]; - name_text = mr2.exp[1]; - } - - inter_type var_type = InterTypes::parse_simple(InterBookmark::scope(IBM), eloc, kind_text, E); - if (*E) return; - - inter_symbol *var_name = TextualInter::new_symbol(eloc, InterBookmark::scope(IBM), name_text, E); - if (*E) return; - - SymbolAnnotation::copy_set_to_symbol(&(ilp->set), var_name); - - inter_pair val = InterValuePairs::undef(); - *E = TextualInter::parse_pair(ilp->line, eloc, IBM, var_type, ilp->mr.exp[1], &val); - if (*E) return; - - *E = VariableInstruction::new(IBM, InterSymbolsTable::id_from_symbol_at_bookmark(IBM, var_name), var_type, val, (inter_ti) ilp->indent_level, eloc); -} - -inter_error_message *VariableInstruction::new(inter_bookmark *IBM, inter_ti VID, inter_type var_type, inter_pair val, inter_ti level, inter_error_location *eloc) { - inter_tree_node *P = Inode::new_with_4_data_fields(IBM, VARIABLE_IST, VID, InterTypes::to_TID_at(IBM, var_type), InterValuePairs::to_word1(val), InterValuePairs::to_word2(val), eloc, level); +inter_error_message *VariableInstruction::new(inter_bookmark *IBM, inter_symbol *var_s, + inter_type var_type, inter_pair val, inter_ti level, inter_error_location *eloc) { + inter_tree_node *P = Inode::new_with_4_data_fields(IBM, VARIABLE_IST, + /* DEFN_VAR_IFLD: */ InterSymbolsTable::id_from_symbol_at_bookmark(IBM, var_s), + /* TYPE_VAR_IFLD: */ InterTypes::to_TID_at(IBM, var_type), + /* VAL1_VAR_IFLD: */ InterValuePairs::to_word1(val), + /* VAL2_VAR_IFLD: */ InterValuePairs::to_word2(val), + eloc, level); inter_error_message *E = VerifyingInter::instruction(InterBookmark::package(IBM), P); if (E) return E; NodePlacement::move_to_moving_bookmark(P, IBM); return NULL; } -void VariableInstruction::verify(inter_construct *IC, inter_tree_node *P, inter_package *owner, inter_error_message **E) { - *E = VerifyingInter::TID_field(owner, P, KIND_VAR_IFLD); if (*E) return; - inter_type type = InterTypes::from_TID_in_field(P, KIND_VAR_IFLD); - *E = VerifyingInter::data_pair_fields(owner, P, VAL1_VAR_IFLD, type); if (*E) return; +@ Verification consists only of sanity checks. + += +void VariableInstruction::verify(inter_construct *IC, inter_tree_node *P, + inter_package *owner, inter_error_message **E) { + *E = VerifyingInter::TID_field(owner, P, TYPE_VAR_IFLD); + if (*E) return; + inter_type type = InterTypes::from_TID_in_field(P, TYPE_VAR_IFLD); + *E = VerifyingInter::data_pair_fields(owner, P, VAL1_VAR_IFLD, type); + if (*E) return; } -void VariableInstruction::write(inter_construct *IC, OUTPUT_STREAM, inter_tree_node *P, inter_error_message **E) { - inter_symbol *var_name = InterSymbolsTable::symbol_from_ID_at_node(P, DEFN_VAR_IFLD); - if (var_name) { - WRITE("variable "); - TextualInter::write_optional_type_marker(OUT, P, KIND_VAR_IFLD); - WRITE("%S = ", InterSymbol::identifier(var_name)); - TextualInter::write_pair(OUT, P, InterValuePairs::get(P, VAL1_VAR_IFLD), FALSE); - SymbolAnnotation::write_annotations(OUT, P, var_name); - } else { *E = Inode::error(P, I"cannot write variable", NULL); return; } +@h Creating from textual Inter syntax. + += +void VariableInstruction::read(inter_construct *IC, inter_bookmark *IBM, + inter_line_parse *ilp, inter_error_location *eloc, inter_error_message **E) { + text_stream *type_text = NULL, *name_text = ilp->mr.exp[0]; + match_results mr = Regexp::create_mr(); + if (Regexp::match(&mr, name_text, L"%((%c+)%) (%c+)")) { + type_text = mr.exp[0]; name_text = mr.exp[1]; + } + inter_type var_type = + InterTypes::parse_simple(InterBookmark::scope(IBM), eloc, type_text, E); + inter_symbol *var_s = NULL; + if (*E == NULL) + var_s = TextualInter::new_symbol(eloc, InterBookmark::scope(IBM), name_text, E); + Regexp::dispose_of(&mr); + if (*E) return; + + SymbolAnnotation::copy_set_to_symbol(&(ilp->set), var_s); + + inter_pair val = InterValuePairs::undef(); + *E = TextualInter::parse_pair(ilp->line, eloc, IBM, var_type, ilp->mr.exp[1], &val); + if (*E) return; + + *E = VariableInstruction::new(IBM, var_s, var_type, val, + (inter_ti) ilp->indent_level, eloc); +} + +@h Writing to textual Inter syntax. + += +void VariableInstruction::write(inter_construct *IC, OUTPUT_STREAM, inter_tree_node *P, + inter_error_message **E) { + inter_symbol *var_s = VariableInstruction::variable(P); + WRITE("variable "); + TextualInter::write_optional_type_marker(OUT, P, TYPE_VAR_IFLD); + WRITE("%S = ", InterSymbol::identifier(var_s)); + TextualInter::write_pair(OUT, P, VariableInstruction::value(P), FALSE); + SymbolAnnotation::write_annotations(OUT, P, var_s); +} + +@h Access functions. + += +inter_symbol *VariableInstruction::variable(inter_tree_node *P) { + if (P == NULL) return NULL; + if (P->W.instruction[ID_IFLD] != VARIABLE_IST) return NULL; + return InterSymbolsTable::symbol_from_ID_at_node(P, DEFN_VAR_IFLD); +} + +inter_pair VariableInstruction::value(inter_tree_node *P) { + if (P == NULL) return InterValuePairs::undef(); + if (P->W.instruction[ID_IFLD] != VARIABLE_IST) return InterValuePairs::undef(); + return InterValuePairs::get(P, VAL1_VAR_IFLD); } diff --git a/inter/final-module/Chapter 2/Code Generation.w b/inter/final-module/Chapter 2/Code Generation.w index ae80d8c26..b26f15809 100644 --- a/inter/final-module/Chapter 2/Code Generation.w +++ b/inter/final-module/Chapter 2/Code Generation.w @@ -120,7 +120,7 @@ void CodeGen::gather_up(inter_tree *I, inter_tree_node *P, void *state) { code_generation *gen = (code_generation *) state; switch (P->W.instruction[ID_IFLD]) { case VARIABLE_IST: { - inter_symbol *var_name = InterSymbolsTable::symbol_from_ID_at_node(P, DEFN_VAR_IFLD); + inter_symbol *var_name = VariableInstruction::variable(P); ADD_TO_LINKED_LIST(var_name, inter_symbol, gen->global_variables); break; } diff --git a/inter/final-module/Chapter 4/Inform 6 Global Variables.w b/inter/final-module/Chapter 4/Inform 6 Global Variables.w index e2b106fa7..1ab58c10a 100644 --- a/inter/final-module/Chapter 4/Inform 6 Global Variables.w +++ b/inter/final-module/Chapter 4/Inform 6 Global Variables.w @@ -22,7 +22,7 @@ void I6TargetVariables::declare_variables(code_generator *gtr, code_generation * inter_symbol *var_name; LOOP_OVER_LINKED_LIST(var_name, inter_symbol, L) { inter_tree_node *P = var_name->definition; - inter_pair val = InterValuePairs::get(P, VAL1_VAR_IFLD); + inter_pair val = VariableInstruction::value(P); if (SymbolAnnotation::get_b(var_name, ASSIMILATED_IANN) == FALSE) { if (k == 1) @; @; diff --git a/inter/final-module/Chapter 5/C Global Variables.w b/inter/final-module/Chapter 5/C Global Variables.w index de9f1e0fd..bf93c85d2 100644 --- a/inter/final-module/Chapter 5/C Global Variables.w +++ b/inter/final-module/Chapter 5/C Global Variables.w @@ -93,7 +93,7 @@ void CGlobals::declare_variables(code_generator *gtr, code_generation *gen, link WRITE(", "); if (var_name->definition) { inter_tree_node *P = var_name->definition; - CodeGen::pair(gen, P, InterValuePairs::get(P, VAL1_VAR_IFLD)); + CodeGen::pair(gen, P, VariableInstruction::value(P)); } else { WRITE("0"); } diff --git a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w index d87c0ac1c..570c95269 100644 --- a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w +++ b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w @@ -341,20 +341,20 @@ not already there. inter_ti B = (inter_ti) InterBookmark::baseline(IBM) + 1; inter_pair val = InterValuePairs::undef(); @; - Produce::guard(ConstantInstruction::new(IBM, made_s, - InterTypes::unchecked(), val, B, NULL)); + Produce::guard(ConstantInstruction::new(IBM, made_s, InterTypes::unchecked(), + val, B, NULL)); @ = - inter_ti MID = InterSymbolsTable::id_from_symbol(I, InterBookmark::package(IBM), made_s); inter_ti B = (inter_ti) InterBookmark::baseline(IBM) + 1; inter_pair val = InterValuePairs::undef(); @; - Produce::guard(VariableInstruction::new(IBM, MID, - InterTypes::unchecked(), val, B, NULL)); + Produce::guard(VariableInstruction::new(IBM, made_s, InterTypes::unchecked(), + val, B, NULL)); @ = inter_ti B = (inter_ti) InterBookmark::baseline(IBM) + 1; - Produce::guard(PropertyInstruction::new(IBM, made_s, InterTypes::unchecked(), B, NULL)); + Produce::guard(PropertyInstruction::new(IBM, made_s, InterTypes::unchecked(), + B, NULL)); @ = inter_ti B = (inter_ti) InterBookmark::baseline(IBM) + 1;