Skip to content

Commit 10ea3cf

Browse files
committed
[[ LCB ]] Implement simple constants.
Simple constant definitions of the form 'constant ID is VALUE' now work where VALUE is a constant value (undefined, true, false, an integer, a real or a string). Constants can be public, in which case they will be accessible from other modules.
1 parent a424e8f commit 10ea3cf

File tree

11 files changed

+206
-59
lines changed

11 files changed

+206
-59
lines changed

libscript/include/script.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ void MCScriptAddExportToModule(MCScriptModuleBuilderRef builder, uindex_t index)
282282
void MCScriptAddImportToModule(MCScriptModuleBuilderRef builder, uindex_t module_index, MCNameRef definition, MCScriptDefinitionKind kind, uindex_t type, uindex_t& r_index);
283283
void MCScriptAddImportToModuleWithIndex(MCScriptModuleBuilderRef builder, uindex_t module_index, MCNameRef definition, MCScriptDefinitionKind kind, uindex_t type, uindex_t p_index);
284284

285+
void MCScriptAddValueToModule(MCScriptModuleBuilderRef builder, MCValueRef value, uindex_t& r_index);
286+
285287
void MCScriptAddDefinedTypeToModule(MCScriptModuleBuilderRef builder, uindex_t index, uindex_t& r_type);
286288
void MCScriptAddForeignTypeToModule(MCScriptModuleBuilderRef builder, MCStringRef p_binding, uindex_t& r_type);
287289
void MCScriptAddOptionalTypeToModule(MCScriptModuleBuilderRef builder, uindex_t type, uindex_t& r_new_type);
@@ -295,7 +297,7 @@ void MCScriptEndRecordTypeInModule(MCScriptModuleBuilderRef builder, uindex_t& r
295297
void MCScriptAddDefinitionToModule(MCScriptModuleBuilderRef builder, uindex_t& r_index);
296298

297299
void MCScriptAddTypeToModule(MCScriptModuleBuilderRef builder, MCNameRef name, uindex_t type, uindex_t index);
298-
void MCScriptAddConstantToModule(MCScriptModuleBuilderRef builder, MCNameRef name, MCValueRef value, uindex_t index);
300+
void MCScriptAddConstantToModule(MCScriptModuleBuilderRef builder, MCNameRef name, uindex_t const_idx, uindex_t index);
299301
void MCScriptAddVariableToModule(MCScriptModuleBuilderRef builder, MCNameRef name, uindex_t type, uindex_t index);
300302

301303
void MCScriptBeginHandlerInModule(MCScriptModuleBuilderRef builder, MCNameRef name, uindex_t signature, uindex_t index);
@@ -329,7 +331,7 @@ void MCScriptEmitJumpIfUndefinedInModule(MCScriptModuleBuilderRef builder, uinde
329331
void MCScriptEmitJumpIfDefinedInModule(MCScriptModuleBuilderRef builder, uindex_t value_reg, uindex_t target_label);
330332
void MCScriptEmitJumpIfFalseInModule(MCScriptModuleBuilderRef builder, uindex_t value_reg, uindex_t target_label);
331333
void MCScriptEmitJumpIfTrueInModule(MCScriptModuleBuilderRef builder, uindex_t value_reg, uindex_t target_label);
332-
void MCScriptEmitAssignConstantInModule(MCScriptModuleBuilderRef builder, uindex_t dst_reg, MCValueRef constant);
334+
void MCScriptEmitAssignConstantInModule(MCScriptModuleBuilderRef builder, uindex_t dst_reg, uindex_t const_idx);
333335
void MCScriptEmitAssignInModule(MCScriptModuleBuilderRef builder, uindex_t dst_reg, uindex_t src_reg);
334336
void MCScriptEmitBeginAssignListInModule(MCScriptModuleBuilderRef builder, uindex_t reg);
335337
void MCScriptEmitContinueAssignListInModule(MCScriptModuleBuilderRef builder, uindex_t reg);

libscript/src/script-builder.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,14 @@ void MCScriptAddDefinitionToModule(MCScriptModuleBuilderRef self, uindex_t& r_in
274274
}
275275
}
276276

277+
void MCScriptAddValueToModule(MCScriptModuleBuilderRef self, MCValueRef p_value, uindex_t& r_index)
278+
{
279+
if (self == nil || !self -> valid)
280+
return;
281+
282+
__emit_constant(self, p_value, r_index);
283+
}
284+
277285
void MCScriptAddTypeToModule(MCScriptModuleBuilderRef self, MCNameRef p_name, uindex_t p_type, uindex_t p_index)
278286
{
279287
if (self == nil || !self -> valid)
@@ -296,7 +304,7 @@ void MCScriptAddTypeToModule(MCScriptModuleBuilderRef self, MCNameRef p_name, ui
296304
t_definition -> type = p_type;
297305
}
298306

299-
void MCScriptAddConstantToModule(MCScriptModuleBuilderRef self, MCNameRef p_name, MCValueRef p_value, uindex_t p_index)
307+
void MCScriptAddConstantToModule(MCScriptModuleBuilderRef self, MCNameRef p_name, uindex_t p_const_idx, uindex_t p_index)
300308
{
301309
if (self == nil || !self -> valid)
302310
return;
@@ -315,7 +323,7 @@ void MCScriptAddConstantToModule(MCScriptModuleBuilderRef self, MCNameRef p_name
315323
t_definition = static_cast<MCScriptConstantDefinition *>(self -> module . definitions[p_index]);
316324

317325
t_definition -> kind = kMCScriptDefinitionKindConstant;
318-
t_definition -> value = MCValueRetain(p_value);
326+
t_definition -> value = p_const_idx;
319327
}
320328

321329
void MCScriptAddVariableToModule(MCScriptModuleBuilderRef self, MCNameRef p_name, uindex_t p_type, uindex_t p_index)
@@ -988,7 +996,7 @@ static void __emit_constant(MCScriptModuleBuilderRef self, MCValueRef p_constant
988996
for(uindex_t i = 0; i < self -> module . value_count; i++)
989997
if (MCValueIsEqualTo(p_constant, self -> module . values[i]))
990998
{
991-
r_index = i + 1;
999+
r_index = i;
9921000
return;
9931001
}
9941002

@@ -998,7 +1006,7 @@ static void __emit_constant(MCScriptModuleBuilderRef self, MCValueRef p_constant
9981006

9991007
self -> module . values[t_vindex] = MCValueRetain(p_constant);
10001008

1001-
r_index = t_vindex + 1;
1009+
r_index = t_vindex;
10021010
}
10031011

10041012
static void __begin_instruction(MCScriptModuleBuilderRef self, MCScriptBytecodeOp p_operation)
@@ -1277,15 +1285,12 @@ void MCScriptEmitJumpIfTrueInModule(MCScriptModuleBuilderRef self, uindex_t p_va
12771285
__emit_instruction(self, kMCScriptBytecodeOpJumpIfTrue, 2, p_value_reg, p_target_label);
12781286
}
12791287

1280-
void MCScriptEmitAssignConstantInModule(MCScriptModuleBuilderRef self, uindex_t p_reg, MCValueRef p_constant)
1288+
void MCScriptEmitAssignConstantInModule(MCScriptModuleBuilderRef self, uindex_t p_reg, uindex_t p_const_idx)
12811289
{
12821290
if (self == nil || !self -> valid)
12831291
return;
12841292

1285-
uindex_t t_constant_index;
1286-
__emit_constant(self, p_constant, t_constant_index);
1287-
1288-
__emit_instruction(self, kMCScriptBytecodeOpAssignConstant, 2, p_reg, t_constant_index - 1);
1293+
__emit_instruction(self, kMCScriptBytecodeOpAssignConstant, 2, p_reg, p_const_idx);
12891294
}
12901295

12911296
void MCScriptEmitBeginAssignListInModule(MCScriptModuleBuilderRef self, uindex_t p_reg)

libscript/src/script-instance.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,8 +2122,10 @@ bool MCScriptCallHandlerOfInstanceInternal(MCScriptInstanceRef self, MCScriptHan
21222122
MCScriptDefinition *t_definition;
21232123
MCScriptResolveDefinitionInFrame(t_frame, t_index, t_instance, t_definition);
21242124

2125-
// Fetch the value - if it is a variable fetch from the slot; if
2126-
// it is a handler construct a handler value.
2125+
// Fetch the value:
2126+
// - variables get fetched from the slot
2127+
// - constants from the constant pool
2128+
// - handlers have a value constructed
21272129
if (t_definition -> kind == kMCScriptDefinitionKindVariable)
21282130
{
21292131
MCScriptVariableDefinition *t_var_definition;
@@ -2139,6 +2141,18 @@ bool MCScriptCallHandlerOfInstanceInternal(MCScriptInstanceRef self, MCScriptHan
21392141
if (t_success)
21402142
t_success = MCScriptCheckedStoreToRegisterInFrame(t_frame, t_dst, t_value);
21412143
}
2144+
else if (t_definition -> kind == kMCScriptDefinitionKindConstant)
2145+
{
2146+
MCScriptConstantDefinition *t_constant_definition;
2147+
t_constant_definition = static_cast<MCScriptConstantDefinition *>(t_definition);
2148+
2149+
MCValueRef t_value;
2150+
t_value = t_instance -> module -> values[t_constant_definition -> value];
2151+
2152+
if (t_success)
2153+
t_success = MCScriptCheckedStoreToRegisterInFrame(t_frame, t_dst, t_value);
2154+
2155+
}
21422156
else if (t_definition -> kind == kMCScriptDefinitionKindHandler)
21432157
{
21442158
MCScriptHandlerDefinition *t_handler_definition;

libscript/src/script-module.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ MC_PICKLE_BEGIN_RECORD(MCScriptTypeDefinition)
118118
MC_PICKLE_END_RECORD()
119119

120120
MC_PICKLE_BEGIN_RECORD(MCScriptConstantDefinition)
121-
MC_PICKLE_VALUEREF(value)
121+
MC_PICKLE_UINDEX(value)
122122
MC_PICKLE_END_RECORD()
123123

124124
MC_PICKLE_BEGIN_RECORD(MCScriptVariableDefinition)
@@ -1090,6 +1090,11 @@ bool MCScriptWriteInterfaceOfModule(MCScriptModuleRef self, MCStreamRef stream)
10901090
}
10911091
}
10921092
break;
1093+
case kMCScriptDefinitionKindConstant:
1094+
{
1095+
__writeln(stream, "constant %@", t_def_name);
1096+
}
1097+
break;
10931098
case kMCScriptDefinitionKindVariable:
10941099
{
10951100
MCAutoStringRef t_type_string;

libscript/src/script-private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ struct MCScriptTypeDefinition: public MCScriptDefinition
240240

241241
struct MCScriptConstantDefinition: public MCScriptDefinition
242242
{
243-
MCValueRef value;
243+
uindex_t value;
244244
};
245245

246246
struct MCScriptVariableDefinition: public MCScriptDefinition

toolchain/lc-compile/src/check.g

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119
--
120120

121121
'rule' CheckBindings(EXPRESSION'slot(_, Name)):
122-
/* BE1 */ CheckBindingIsVariableOrHandlerId(Name)
122+
/* BE1 */ CheckBindingIsConstantOrVariableOrHandlerId(Name)
123123
124124
'rule' CheckBindings(EXPRESSION'call(_, Handler, Arguments)):
125125
/* BE2 */ CheckBindingIsCallableVariableOrHandlerId(Handler)
@@ -234,6 +234,34 @@
234234
-- Mark this id as being in error.
235235
Id'Meaning <- error
236236
237+
'action' CheckBindingIsConstantOrVariableOrHandlerId(ID)
238+
239+
'rule' CheckBindingIsConstantOrVariableOrHandlerId(Id):
240+
-- Do nothing if the meaning is error.
241+
QueryId(Id -> error)
242+
243+
'rule' CheckBindingIsConstantOrVariableOrHandlerId(Id):
244+
QueryKindOfSymbolId(Id -> constant)
245+
246+
'rule' CheckBindingIsConstantOrVariableOrHandlerId(Id):
247+
QueryKindOfSymbolId(Id -> variable)
248+
249+
'rule' CheckBindingIsConstantOrVariableOrHandlerId(Id):
250+
QueryKindOfSymbolId(Id -> parameter)
251+
252+
'rule' CheckBindingIsConstantOrVariableOrHandlerId(Id):
253+
QueryKindOfSymbolId(Id -> local)
254+
255+
'rule' CheckBindingIsConstantOrVariableOrHandlerId(Id):
256+
QueryKindOfSymbolId(Id -> handler)
257+
258+
'rule' CheckBindingIsConstantOrVariableOrHandlerId(Id):
259+
Id'Name -> Name
260+
Id'Position -> Position
261+
Error_NotBoundToAConstantOrVariableOrHandler(Position, Name)
262+
-- Mark this id as being in error.
263+
Id'Meaning <- error
264+
237265
'action' FullyResolveType(TYPE -> TYPE)
238266

239267
'rule' FullyResolveType(optional(_, Type) -> Base):
@@ -1179,7 +1207,7 @@
11791207
CheckExpressionIsAssignable(Target)
11801208
CheckInvokes(Source)
11811209
CheckInvokes(Target)
1182-
1210+
11831211
'rule' CheckInvokes(STATEMENT'repeatcounted(Position, Count, Body)):
11841212
CheckExpressionIsEvaluatable(Count)
11851213
CheckInvokes(Count)
@@ -1354,11 +1382,16 @@
13541382
|)
13551383
13561384
'rule' CheckExpressionIsAssignable(slot(Position, Id)):
1357-
[|
1385+
(|
13581386
QueryKindOfSymbolId(Id -> handler)
13591387
Id'Name -> Name
13601388
Error_CannotAssignToHandlerId(Position, Name)
1361-
|]
1389+
||
1390+
QueryKindOfSymbolId(Id -> constant)
1391+
Id'Name -> Name
1392+
Error_CannotAssignToConstantId(Position, Name)
1393+
||
1394+
|)
13621395
13631396
'rule' CheckExpressionIsAssignable(Expr):
13641397
-- everything else is not

toolchain/lc-compile/src/emit.cpp

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ extern "C" void EmitImportedSyntax(long p_module_index, NameRef p_name, long p_t
4040
extern "C" void EmitExportedDefinition(long index);
4141
extern "C" void EmitDefinitionIndex(long& r_index);
4242
extern "C" void EmitTypeDefinition(long index, PositionRef position, NameRef name, long type_index);
43+
extern "C" void EmitConstantDefinition(long p_index, PositionRef p_position, NameRef p_name, long p_const_index);
4344
extern "C" void EmitVariableDefinition(long index, PositionRef position, NameRef name, long type_index);
4445
extern "C" void EmitBeginHandlerDefinition(long index, PositionRef position, NameRef name, long type_index);
4546
extern "C" void EmitEndHandlerDefinition(void);
@@ -119,12 +120,13 @@ extern "C" void EmitBeginIndirectInvoke(long handlerreg, long contextreg, long r
119120
extern "C" void EmitContinueInvoke(long reg);
120121
extern "C" void EmitEndInvoke(void);
121122
extern "C" void EmitAssign(long dst, long src);
122-
extern "C" void EmitAssignUndefined(long reg);
123-
extern "C" void EmitAssignTrue(long reg);
124-
extern "C" void EmitAssignFalse(long reg);
125-
extern "C" void EmitAssignInteger(long reg, long value);
126-
extern "C" void EmitAssignReal(long reg, long value);
127-
extern "C" void EmitAssignString(long reg, long value);
123+
extern "C" void EmitAssignConstant(long dst, long constidx);
124+
extern "C" void EmitUndefinedConstant(long *idx);
125+
extern "C" void EmitTrueConstant(long *idx);
126+
extern "C" void EmitFalseConstant(long *idx);
127+
extern "C" void EmitIntegerConstant(long value, long *idx);
128+
extern "C" void EmitRealConstant(long value, long *idx);
129+
extern "C" void EmitStringConstant(long value, long *idx);
128130
extern "C" void EmitBeginAssignList(long reg);
129131
extern "C" void EmitContinueAssignList(long reg);
130132
extern "C" void EmitEndAssignList(void);
@@ -421,6 +423,13 @@ void EmitTypeDefinition(long p_index, PositionRef p_position, NameRef p_name, lo
421423
MCLog("[Emit] TypeDefinition(%ld, %@, %ld)", p_index, to_mcnameref(p_name), p_type_index);
422424
}
423425

426+
void EmitConstantDefinition(long p_index, PositionRef p_position, NameRef p_name, long p_const_index)
427+
{
428+
MCScriptAddConstantToModule(s_builder, to_mcnameref(p_name), p_const_index, p_index);
429+
430+
MCLog("[Emit] ConstantDefinition(%ld, %@, %ld)", p_index, to_mcnameref(p_name), p_const_index);
431+
}
432+
424433
void EmitVariableDefinition(long p_index, PositionRef p_position, NameRef p_name, long p_type_index)
425434
{
426435
MCScriptAddVariableToModule(s_builder, to_mcnameref(p_name), p_type_index, p_index);
@@ -1068,46 +1077,46 @@ void EmitEndInvoke(void)
10681077

10691078
//////////
10701079

1071-
void EmitAssignUndefined(long reg)
1080+
void EmitUndefinedConstant(long *idx)
10721081
{
1073-
MCScriptEmitAssignConstantInModule(s_builder, reg, kMCNull);
1074-
MCLog("[Emit] AssignUndefined(%ld)", reg);
1082+
MCScriptAddValueToModule(s_builder, kMCNull, (uindex_t&)*idx);
1083+
MCLog("[Emit] UndefinedConstant(-> %ld)", *idx);
10751084
}
10761085

1077-
void EmitAssignTrue(long reg)
1086+
void EmitTrueConstant(long *idx)
10781087
{
1079-
MCScriptEmitAssignConstantInModule(s_builder, reg, kMCTrue);
1080-
MCLog("[Emit] AssignUndefined(%ld)", reg);
1088+
MCScriptAddValueToModule(s_builder, kMCTrue, (uindex_t&)*idx);
1089+
MCLog("[Emit] TrueConstant(-> %ld)", *idx);
10811090
}
10821091

1083-
void EmitAssignFalse(long reg)
1092+
void EmitFalseConstant(long *idx)
10841093
{
1085-
MCScriptEmitAssignConstantInModule(s_builder, reg, kMCFalse);
1086-
MCLog("[Emit] AssignUndefined(%ld)", reg);
1094+
MCScriptAddValueToModule(s_builder, kMCFalse, (uindex_t&)*idx);
1095+
MCLog("[Emit] FalseConstant(%ld)", *idx);
10871096
}
10881097

1089-
void EmitAssignInteger(long reg, long value)
1098+
void EmitIntegerConstant(long value, long *idx)
10901099
{
10911100
MCAutoNumberRef t_number;
10921101
MCNumberCreateWithInteger(value, &t_number);
1093-
MCScriptEmitAssignConstantInModule(s_builder, reg, *t_number);
1094-
MCLog("[Emit] AssignInteger(%ld, %ld)", reg, value);
1102+
MCScriptAddValueToModule(s_builder, *t_number, (uindex_t&)*idx);
1103+
MCLog("[Emit] IntegerConstant(%ld -> %ld)", value, *idx);
10951104
}
10961105

1097-
void EmitAssignReal(long reg, long value)
1106+
void EmitRealConstant(long value, long *idx)
10981107
{
10991108
MCAutoNumberRef t_number;
11001109
MCNumberCreateWithReal(*(double *)value, &t_number);
1101-
MCScriptEmitAssignConstantInModule(s_builder, reg, *t_number);
1102-
MCLog("[Emit] AssignReal(%ld, %lf)", reg, *(double *)value);
1110+
MCScriptAddValueToModule(s_builder, *t_number, (uindex_t&)*idx);
1111+
MCLog("[Emit] RealConstant(%lf -> %ld)", *(double *)value, *idx);
11031112
}
11041113

1105-
void EmitAssignString(long reg, long value)
1114+
void EmitStringConstant(long value, long *idx)
11061115
{
11071116
MCAutoStringRef t_string;
11081117
MCStringCreateWithBytes((const byte_t *)value, strlen((const char *)value), kMCStringEncodingUTF8, false, &t_string);
1109-
MCScriptEmitAssignConstantInModule(s_builder, reg, *t_string);
1110-
MCLog("[Emit] AssignString(%ld, \"%s\")", reg, (const char *)value);
1118+
MCScriptAddValueToModule(s_builder, *t_string, (uindex_t&)*idx);
1119+
MCLog("[Emit] StringConstant(\"%s\" -> %ld)", (const char *)value, *idx);
11111120
}
11121121

11131122
void EmitBeginAssignList(long reg)
@@ -1134,12 +1143,18 @@ void EmitAssign(long dst, long src)
11341143
MCLog("[Emit] Assign(%ld, %ld)", dst, src);
11351144
}
11361145

1146+
void EmitAssignConstant(long dst, long idx)
1147+
{
1148+
MCScriptEmitAssignConstantInModule(s_builder, dst, idx);
1149+
MCLog("[Emit] AssignConstant(%ld, %ld)", dst, idx);
1150+
}
1151+
11371152
/////////
11381153

11391154
void EmitFetch(long reg, long var, long level)
11401155
{
11411156
MCScriptEmitFetchInModule(s_builder, reg, var, level);
1142-
MCLog("[Emit] Fetch(%ld, %ld, $ld)", reg, var, level);
1157+
MCLog("[Emit] Fetch(%ld, %ld, %ld)", reg, var, level);
11431158
}
11441159

11451160
void EmitStore(long reg, long var, long level)

0 commit comments

Comments
 (0)