1
2
3
4
5
6 using IntermediateCodeTokens;
7
8 parser IntermediateCodeFileParser
9 {
10 uselexer IntermediateCodeLexer;
11 main;
12
13 IntermediateCodeFile(cmsx.intermediate.Context* context)
14 ::= empty{ context->SetFileName(lexer.FileName()); }
15 CompileUnitHeader(context):header
16 TypeDeclarations(context):typeDeclarations?
17 DataDefinitions(context):dataDefinitions?
18 Functions(context):functions?
19 Metadata(context):metadata?
20 ;
21
22 CompileUnitHeader(cmsx.intermediate.Context* context)
23 ::= CU LPAREN! CompileUnitId:cuid! COMMA! MDStructRef(context):mdRef! RPAREN!
24 {
25 context->SetCompileUnitInfo(cuid, mdRef);
26 }
27 ;
28
29 CompileUnitId : string
30 ::= HEXNUM{ return ToUtf8(lexer.GetToken(pos).match.ToString()); }
31 | NUMBER{ return ToUtf8(lexer.GetToken(pos).match.ToString()); }
32 | ID{ return ToUtf8(lexer.GetToken(pos).match.ToString()); }
33 ;
34
35 TypeDeclarations(cmsx.intermediate.Context* context)
36 ::= TYPES LBRACE! TypeDeclaration(context):typeDeclaration* RBRACE!{ context->ResolveTypes(); }
37 ;
38
39 TypeDeclaration(cmsx.intermediate.Context* context, var string typeId)
40 ::= StrTypeId(context):tid{ typeId = tid; } ASSIGN! TYPE!
41 ( StructureType(typeId, context):structureType
42 | ArrayType(typeId, context):arrayType
43 | FunctionType(typeId, context):functionType
44 )
45 ;
46
47 StrTypeId(cmsx.intermediate.Context* context, var string str) : string
48 ::=
49 (
50 ( TYPEID{ str = ToUtf8(lexer.GetToken(pos).match.ToString()); }
51 | PrimitiveTypeName:primitiveTypeName{ str = primitiveTypeName; }
52 )
53 (AST{ str.Append('*'); context->AddPtrType(str, span.line); })*
54 )
55 {
56 return str;
57 }
58 ;
59
60 StructureType(string typeId, cmsx.intermediate.Context* context, var List<string> memberTypeIds)
61 ::= (LBRACE ((StrTypeId(context):tid!{ memberTypeIds.Add(tid); } (COLON OFFSET ASSIGN NUMBER)?) % COMMA) RBRACE!){ context->AddStructureType(typeId, memberTypeIds); }
62 (SIZE ASSIGN NUMBER COMMA ALIGNMENT ASSIGN NUMBER)?
63 ;
64
65 ArrayType(string typeId, cmsx.intermediate.Context* context, var long size)
66 ::=
67 ( LBRACKET
68 NUMBER!{ size = ParseLong(ToUtf8(lexer.GetToken(pos).match.ToString())); }
69 ID{ pass = lexer.GetToken(pos).match.ToString() == u"x"; }
70 StrTypeId(context):elementTypeId!
71 RBRACKET!
72 )
73 {
74 context->AddArrayType(typeId, elementTypeId, size);
75 }
76 (SIZE ASSIGN NUMBER COMMA ALIGNMENT ASSIGN NUMBER)?
77 ;
78
79 FunctionType(string typeId, cmsx.intermediate.Context* context, var List<string> paramTypeIds)
80 ::=
81 (
82 FUNCTION StrTypeId(context):returnTypeId! LPAREN! (StrTypeId(context):paramType{ paramTypeIds.Add(paramType); } % COMMA)? RPAREN!
83 )
84 {
85 context->AddFunctionType(typeId, returnTypeId, paramTypeIds);
86 }
87 ;
88
89 DataDefinitions(cmsx.intermediate.Context* context)
90 ::= (DATA LBRACE! DataDefinition(context):dataDefinition* RBRACE!){ context->ValidateGlobalVariables(); }
91 ;
92
93 DataDefinition(cmsx.intermediate.Context* context, var bool once, var string variableName, var cmsx.intermediate.Type* type)
94 ::= TypeExpr(context):t{ type = t; } (ONCE{ once = true; })? ID!{ variableName = ToUtf8(lexer.GetToken(pos).match.ToString()); }
95 ( SEMICOLON{ context->AddGlobalVariable(type, variableName, cast<cmsx.intermediate.ConstantValue*>(null), span.line, once); }
96 | ASSIGN! Constant(context):constant{ context->AddGlobalVariable(type, variableName, constant, span.line, once); }
97 )
98 ;
99
100 Functions(cmsx.intermediate.Context* context)
101 ::= Function(context):function*
102 ;
103
104 Function(cmsx.intermediate.Context* context, var cmsx.intermediate.Function* function)
105 ::= FunctionHeader(context):fun{ function = fun; context->SetCurrentFunction(function); } LBRACE! BasicBlock(context, function):bb* RBRACE!
106 ;
107
108 FunctionHeader(cmsx.intermediate.Context* context, var bool once, var string functionId, var cmsx.intermediate.Type* functionType) : cmsx.intermediate.Function*
109 ::= FUNCTION TypeExpr(context):t!{ functionType = t; } (ONCE{ once = true; })? ID!{ functionId = ToUtf8(lexer.GetToken(pos).match.ToString()); } (MDStructRef(context):md?)
110 {
111 return context->AddFunction(span.line, functionType, functionId, once, md);
112 }
113 ;
114
115 BasicBlock(cmsx.intermediate.Context* context, cmsx.intermediate.Function* function, var cmsx.intermediate.BasicBlock* bb)
116 ::= Label:id{ bb = function->AddBasicBlock(id); } Instructions(context, bb):instructions
117 ;
118
119 Label : uint
120 ::= AT NUMBER{ return ParseUInt(ToUtf8(lexer.GetToken(pos).match.ToString())); }
121 ;
122
123 Instructions(cmsx.intermediate.Context* context, cmsx.intermediate.BasicBlock* bb)
124 ::=
125 (
126 (Instruction(context):instruction (MDStructRef(context):lineInfo)?){ bb->AddInstruction(instruction, lineInfo); }
127 )+
128 ;
129
130 Instruction(cmsx.intermediate.Context* context) : cmsx.intermediate.Instruction*
131 ::= StoreInstruction(context):store{ return store; }
132 | ArgInstruction(context):arg{ return arg; }
133 | JumpInstruction(context):jmp{ return jmp; }
134 | BranchInstruction(context):branch{ return branch; }
135 | ProcedureCallInstruction(context):call{ return call; }
136 | RetInstruction(context):ret{ return ret; }
137 | SwitchInstruction(context):swtch{ return swtch; }
138 | ValueInstruction(context):valueInst{ return valueInst; }
139 | NoOperationInstruction(context):nopInst{ return nopInst; }
140 | SaveInstruction(context):saveInst{ return saveInst; }
141 ;
142
143 StoreInstruction(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* type, var cmsx.intermediate.Type* ptrType) : cmsx.intermediate.Instruction*
144 ::= STORE TypeExpr(context):t!{ type = t; } TypedValue(context, type):val! COMMA! TypeExpr(context):pt!{ ptrType = pt; } TypedValue(context, ptrType):ptr!
145 {
146 return new cmsx.intermediate.StoreInstruction(val, ptr, span.line);
147 }
148 ;
149
150 ArgInstruction(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* type) : cmsx.intermediate.Instruction*
151 ::= ARG TypeExpr(context):t!{ type = t; } TypedValue(context, type):arg!
152 {
153 return new cmsx.intermediate.ArgInstruction(arg, span.line);
154 }
155 ;
156
157 JumpInstruction(cmsx.intermediate.Context* context) : cmsx.intermediate.Instruction*
158 ::= JMP Label:target!
159 {
160 return new cmsx.intermediate.JumpInstruction(target, span.line);
161 }
162 ;
163
164 BranchInstruction(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* type) : cmsx.intermediate.Instruction*
165 ::= BRANCH TypeExpr(context):t!{ type = t; } TypedValue(context, type):cond! COMMA! Label:trueTarget! COMMA! Label:falseTarget!
166 {
167 return new cmsx.intermediate.BranchInstruction(cond, trueTarget, falseTarget, span.line);
168 }
169 ;
170
171 ProcedureCallInstruction(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* functionType) : cmsx.intermediate.Instruction*
172 ::= CALL TypeExpr(context):ft!{ functionType = ft; } TypedValue(context, functionType):callee!
173 {
174 return new cmsx.intermediate.ProcedureCallInstruction(callee, span.line);
175 }
176 ;
177
178 RetInstruction(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* type) : cmsx.intermediate.Instruction*
179 ::= RET
180 ( (VOID - (VOID AST)){ return new cmsx.intermediate.RetInstruction(null, span.line); }
181 | TypeExpr(context):t{ type = t; } TypedValue(context, type):val{ return new cmsx.intermediate.RetInstruction(val, span.line); }
182 )
183 ;
184
185 SwitchInstruction(cmsx.intermediate.Context* context, var cmsx.intermediate.SwitchInstruction* inst, var cmsx.intermediate.Type* type, var cmsx.intermediate.Type* caseType) :
186 cmsx.intermediate.SwitchInstruction*
187 ::=
188 (
189 SWITCH TypeExpr(context):t!{ type = t; } TypedValue(context, type):cond! Label:defaultTarget!{ inst = new cmsx.intermediate.SwitchInstruction(cond, defaultTarget, span.line); }
190 COMMA!
191 LBRACKET! ((TypeExpr(context):ct{ caseType = ct; } TypedValue(context, caseType):caseValue COMMA Label:caseTarget){ inst->AddCase(caseValue, caseTarget); } % COLON) RBRACKET!
192 )
193 {
194 return inst;
195 }
196 ;
197
198 ValueInstruction(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* type, var cmsx.intermediate.Value* result) : cmsx.intermediate.Instruction*
199 ::= TypeExpr(context):t{ type = t; } TypedValue(context, type):r!{ result = r; } ASSIGN Operation(context, result):op!
200 {
201 return op;
202 }
203 ;
204
205 Operation(cmsx.intermediate.Context* context, cmsx.intermediate.Value* result) : cmsx.intermediate.Instruction*
206 ::= UnaryInstruction(context, result):unaryInst{ return unaryInst; }
207 | BinaryInstruction(context, result):binaryInst{ return binaryInst; }
208 | ParamInstruction(context, result):paramInst{ return paramInst; }
209 | LocalInstruction(context, result):localInst{ return localInst; }
210 | LoadInstruction(context, result):loadInst{ return loadInst; }
211 | ElemAddrInstruction(context, result):elemAddrInst{ return elemAddrInst; }
212 | PtrOffsetInstruction(context, result):ptrOffsetInst{ return ptrOffsetInst; }
213 | PtrDiffInstruction(context, result):ptrDiffInst{ return ptrDiffInst; }
214 | FunctionCallInstruction(context, result):functionCallInst{ return functionCallInst; }
215 | TrapInstruction(context, result):trapInst{ return trapInst; }
216 ;
217
218 UnaryInstruction(cmsx.intermediate.Context* context, cmsx.intermediate.Value* result, var cmsx.intermediate.UnaryInstruction* inst) : cmsx.intermediate.Instruction*
219 ::= UnaryInst:unaryInst{ inst = unaryInst; } Operand(context):arg!{ inst->SetOperand(arg); inst->SetResult(result); return inst; }
220 ;
221
222 UnaryInst : cmsx.intermediate.UnaryInstruction*
223 ::= NOT{ return new cmsx.intermediate.NotInstruction(span.line); }
224 | NEG{ return new cmsx.intermediate.NegInstruction(span.line); }
225 | SIGNEXTEND{ return new cmsx.intermediate.SignExtendInstruction(span.line); }
226 | ZEROEXTEND{ return new cmsx.intermediate.ZeroExtendInstruction(span.line); }
227 | TRUNCATE{ return new cmsx.intermediate.TruncateInstruction(span.line); }
228 | BITCAST{ return new cmsx.intermediate.BitCastInstruction(span.line); }
229 | INTTOFLOAT{ return new cmsx.intermediate.IntToFloatInstruction(span.line); }
230 | FLOATTOINT{ return new cmsx.intermediate.FloatToIntInstruction(span.line); }
231 | INTTOPTR{ return new cmsx.intermediate.IntToPtrInstruction(span.line); }
232 | PTRTOINT{ return new cmsx.intermediate.PtrToIntInstruction(span.line); }
233 ;
234
235 BinaryInstruction(cmsx.intermediate.Context* context, cmsx.intermediate.Value* result, var cmsx.intermediate.BinaryInstruction* inst) : cmsx.intermediate.Instruction*
236 ::= BinaryInst:binaryInst{ inst = binaryInst; } Operand(context):left! COMMA! Operand(context):right!{ inst->SetOperands(left, right); inst->SetResult(result); return inst; }
237 ;
238
239 BinaryInst : cmsx.intermediate.BinaryInstruction*
240 ::= ADD{ return new cmsx.intermediate.AddInstruction(span.line); }
241 | SUB{ return new cmsx.intermediate.SubInstruction(span.line); }
242 | MUL{ return new cmsx.intermediate.MulInstruction(span.line); }
243 | DIV{ return new cmsx.intermediate.DivInstruction(span.line); }
244 | MOD{ return new cmsx.intermediate.ModInstruction(span.line); }
245 | AND{ return new cmsx.intermediate.AndInstruction(span.line); }
246 | OR{ return new cmsx.intermediate.OrInstruction(span.line); }
247 | XOR{ return new cmsx.intermediate.XorInstruction(span.line); }
248 | SHL{ return new cmsx.intermediate.ShlInstruction(span.line); }
249 | SHR{ return new cmsx.intermediate.ShrInstruction(span.line); }
250 | EQUAL{ return new cmsx.intermediate.EqualInstruction(span.line); }
251 | LESS{ return new cmsx.intermediate.LessInstruction(span.line); }
252 ;
253
254 ParamInstruction(cmsx.intermediate.Context* context, cmsx.intermediate.Value* result) : cmsx.intermediate.Instruction*
255 ::= PARAM{ return new cmsx.intermediate.ParamInstruction(result, span.line); }
256 ;
257
258 LocalInstruction(cmsx.intermediate.Context* context, cmsx.intermediate.Value* result, var cmsx.intermediate.Type* localType) : cmsx.intermediate.Instruction*
259 ::= (LOCAL TypeExpr(context):t!{ localType = t; }){ return new cmsx.intermediate.LocalInstruction(result, localType, span.line); }
260 ;
261
262 LoadInstruction(cmsx.intermediate.Context* context, cmsx.intermediate.Value* result) : cmsx.intermediate.Instruction*
263 ::= (LOAD Operand(context):ptr!){ return new cmsx.intermediate.LoadInstruction(result, ptr, span.line); }
264 ;
265
266 ElemAddrInstruction(cmsx.intermediate.Context* context, cmsx.intermediate.Value* result) : cmsx.intermediate.Instruction*
267 ::= (ELEMADDR Operand(context):ptr! COMMA! Operand(context):index!){ return new cmsx.intermediate.ElemAddrInstruction(result, ptr, index, span.line); }
268 ;
269
270 PtrOffsetInstruction(cmsx.intermediate.Context* context, cmsx.intermediate.Value* result) : cmsx.intermediate.Instruction*
271 ::= (PTROFFSET Operand(context):ptr! COMMA! Operand(context):offset!){ return new cmsx.intermediate.PtrOffsetInstruction(result, ptr, offset, span.line); }
272 ;
273
274 PtrDiffInstruction(cmsx.intermediate.Context* context, cmsx.intermediate.Value* result) : cmsx.intermediate.Instruction*
275 ::= (PTRDIFF Operand(context):leftPtr! COMMA! Operand(context):rightPtr!){ return new cmsx.intermediate.PtrDiffInstruction(result, leftPtr, rightPtr, span.line); }
276 ;
277
278 FunctionCallInstruction(cmsx.intermediate.Context* context, cmsx.intermediate.Value* result, var cmsx.intermediate.Type* functionType) : cmsx.intermediate.Instruction*
279 ::= (CALL TypeExpr(context):ft!{ functionType = ft; } TypedValue(context, functionType):callee!){ return new cmsx.intermediate.FunctionCallInstruction(result, callee, span.line); }
280 ;
281
282 TrapInstruction(cmsx.intermediate.Context* context, cmsx.intermediate.Value* result, var cmsx.intermediate.Type* type1, var cmsx.intermediate.Type* type2, var cmsx.intermediate.Type* type3) :
283 cmsx.intermediate.Instruction*
284 ::=
285 ( TRAP
286 TypeExpr(context):t1!{ type1 = t1; } TypedValue(context, type1):val1! COMMA!
287 TypeExpr(context):t2!{ type2 = t2; } TypedValue(context, type2):val2! COMMA!
288 TypeExpr(context):t3!{ type3 = t3; } TypedValue(context, type3):val3!
289 )
290 {
291 return new cmsx.intermediate.TrapInstruction(result, val1, val2, val3, span.line);
292 }
293 ;
294
295 NoOperationInstruction(cmsx.intermediate.Context* context) : cmsx.intermediate.Instruction*
296 ::= NOP{ return new cmsx.intermediate.NoOperationInstruction(span.line); }
297 ;
298
299 SaveInstruction(cmsx.intermediate.Context* context) : cmsx.intermediate.Instruction*
300 ::= SAVE{ return new cmsx.intermediate.SaveInstruction(span.line); }
301 ;
302
303 Operand(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* type) : cmsx.intermediate.Value*
304 ::= (TypeExpr(context):t{ type = t; } TypedValue(context, type):val!){ return val; }
305 ;
306
307 TypeExpr(cmsx.intermediate.Context* context) : cmsx.intermediate.Type*
308 ::= PostfixTypeExpr(context):postfix{ return postfix; }
309 ;
310
311 PostfixTypeExpr(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* type) : cmsx.intermediate.Type*
312 ::= (PrimaryTypeExpr(context):primary{ type = primary; } (AST{ type = context->GetPtrType(type); })*){ return type; }
313 ;
314
315 PrimaryTypeExpr(cmsx.intermediate.Context* context) : cmsx.intermediate.Type*
316 ::= TypeId(context):typeId{ return typeId; }
317 | PrimitiveType(context):primitive{ return primitive; }
318 ;
319
320 TypeId(cmsx.intermediate.Context* context) : cmsx.intermediate.Type*
321 ::= TYPEID{ return context->GetTypeById(span.line, ToUtf8(lexer.GetToken(pos).match.ToString())); }
322 ;
323
324 PrimitiveType(cmsx.intermediate.Context* context) : cmsx.intermediate.Type*
325 ::= VOID{ return context->GetVoidType(); }
326 | BOOL{ return context->GetBoolType(); }
327 | SBYTE{ return context->GetSByteType(); }
328 | BYTE{ return context->GetByteType(); }
329 | SHORT{ return context->GetShortType(); }
330 | USHORT{ return context->GetUShortType(); }
331 | INT{ return context->GetIntType(); }
332 | UINT{ return context->GetUIntType(); }
333 | LONG{ return context->GetLongType(); }
334 | ULONG{ return context->GetULongType(); }
335 | FLOAT{ return context->GetFloatType(); }
336 | DOUBLE{ return context->GetDoubleType(); }
337 ;
338
339 PrimitiveTypeName : string
340 ::= VOID{ return "void"; }
341 | BOOL{ return "bool"; }
342 | SBYTE{ return "sbyte"; }
343 | BYTE{ return "byte"; }
344 | SHORT{ return "short"; }
345 | USHORT{ return "ushort"; }
346 | INT{ return "int"; }
347 | UINT{ return "uint"; }
348 | LONG{ return "long"; }
349 | ULONG{ return "ulong"; }
350 | FLOAT{ return "float"; }
351 | DOUBLE{ return "double"; }
352 ;
353
354 TypedValue(cmsx.intermediate.Context* context, cmsx.intermediate.Type* type) : cmsx.intermediate.Value*
355 ::= IdValue(context, type):idValue{ return idValue; }
356 | SymbolValue(context, type):symbolValue{ return symbolValue; }
357 | LiteralValue(context, type):literalValue{ return literalValue; }
358 ;
359
360 IdValue(cmsx.intermediate.Context* context, cmsx.intermediate.Type* type) : cmsx.intermediate.Value*
361 ::= DOLLAR NUMBER{ uint x = ParseUInt(ToUtf8(lexer.GetToken(pos).match.ToString())); return context->currentFunction->MakeIdValue(span.line, x, type); }
362 ;
363
364 SymbolValue(cmsx.intermediate.Context* context, cmsx.intermediate.Type* type) : cmsx.intermediate.ConstantValue*
365 ::= AT ID{ return context->MakeSymbolValue(span.line, ToUtf8(lexer.GetToken(pos).match.ToString()), type); }
366 ;
367
368 LiteralValue(cmsx.intermediate.Context* context, cmsx.intermediate.Type* type) : cmsx.intermediate.ConstantValue*
369 ::= TRUE{ if (type is cmsx.intermediate.BoolType*) return context->GetBoolType()->MakeBoolValue(true); else context->MakeLiteralValue(span.line, ToUtf8(lexer.GetToken(pos).match.ToString()), type); }
370 | FALSE{ if (type is cmsx.intermediate.BoolType*) return context->GetBoolType()->MakeBoolValue(false); else context->MakeLiteralValue(span.line, ToUtf8(lexer.GetToken(pos).match.ToString()), type); }
371 | NULL{ if (type is cmsx.intermediate.PtrType*) return type->DefaultValue(); else context->MakeLiteralValue(span.line, ToUtf8(lexer.GetToken(pos).match.ToString()), type); }
372 | NUMBER{ return context->MakeLiteralValue(span.line, ToUtf8(lexer.GetToken(pos).match.ToString()), type); }
373 | ID{ return context->MakeLiteralValue(span.line, ToUtf8(lexer.GetToken(pos).match.ToString()), type); }
374 ;
375
376 Constant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
377 ::= ConversionConstant(context):conversionConstant{ return conversionConstant; }
378 | ClsIdConstant(context):clsIdConstant{ return clsIdConstant; }
379 | PtrConstant(context):ptrConstant{ return ptrConstant; }
380 | SymbolConstant(context):symbolConstant{ return symbolConstant; }
381 | BoolConstant(context):boolConstant{ return boolConstant; }
382 | SByteConstant(context):sbyteConstant{ return sbyteConstant; }
383 | ByteConstant(context):byteConstant{ return byteConstant; }
384 | ShortConstant(context):shortConstant{ return shortConstant; }
385 | UShortConstant(context):ushortConstant{ return ushortConstant; }
386 | IntConstant(context):intConstant{ return intConstant; }
387 | UIntConstant(context):uintConstant{ return uintConstant; }
388 | LongConstant(context):longConstant{ return longConstant; }
389 | ULongConstant(context):ulongConstant{ return ulongConstant; }
390 | FloatConstant(context):floatConstant{ return floatConstant; }
391 | DoubleConstant(context):doubleConstant{ return doubleConstant; }
392 | ArrayConstant(context):arrayConstant{ return arrayConstant; }
393 | StructureConstant(context):structureConstant{ return structureConstant; }
394 | StringConstant(context):stringConstant{ return stringConstant; }
395 | StringArrayConstant(context):stringArrayConstant{ return stringArrayConstant; }
396 ;
397
398 ConversionConstant(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* targetType) : cmsx.intermediate.ConstantValue*
399 ::= (TypeExpr(context):t{ targetType = t; } CONV LPAREN! Constant(context):from! RPAREN!){ return context->MakeConversionValue(targetType, from, span.line); }
400 ;
401
402 ClsIdConstant(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* type) : cmsx.intermediate.ConstantValue*
403 ::= TypeExpr(context):t{ type = t; } CLSID{ return context->MakeClsIdValue(type, ToUtf8(lexer.GetToken(pos).match.ToString()), span.line); }
404 ;
405
406 PtrConstant(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* type) : cmsx.intermediate.ConstantValue*
407 ::= (TypeExpr(context):type1{ type = type1; pass = cmsx.intermediate.IsPtrType(type); } NULL){ return cast<cmsx.intermediate.PtrType*>(type)->DefaultValue(); }
408 | (TypeExpr(context):type2{ type = type2; pass = cmsx.intermediate.IsPtrType(type); } LiteralValue(context, type):literalValue){ return literalValue; }
409 ;
410
411 SymbolConstant(cmsx.intermediate.Context* context, var cmsx.intermediate.Type* type) : cmsx.intermediate.ConstantValue*
412 ::= TypeExpr(context):t{ type = t; } SymbolValue(context, type):symbolValue{ return symbolValue; }
413 ;
414
415 BoolConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
416 ::= BOOL (TRUE{ return context->GetBoolType()->MakeBoolValue(true); } | FALSE{ return context->GetBoolType()->MakeBoolValue(false); })
417 ;
418
419 SByteConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
420 ::= SBYTE NUMBER{ return context->MakeSByteValue(context->GetSByteType(), ParseSByte(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
421 ;
422
423 ByteConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
424 ::= BYTE NUMBER{ return context->MakeByteValue(context->GetByteType(), ParseByte(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
425 ;
426
427 ShortConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
428 ::= SHORT NUMBER{ return context->MakeShortValue(context->GetShortType(), ParseShort(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
429 ;
430
431 UShortConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
432 ::= USHORT NUMBER{ return context->MakeUShortValue(context->GetUShortType(), ParseUShort(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
433 ;
434
435 IntConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
436 ::= INT NUMBER{ return context->MakeIntValue(context->GetIntType(), ParseInt(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
437 ;
438
439 UIntConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
440 ::= UINT NUMBER{ return context->MakeUIntValue(context->GetUIntType(), ParseUInt(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
441 ;
442
443 LongConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
444 ::= LONG NUMBER{ return context->MakeLongValue(context->GetLongType(), ParseLong(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
445 ;
446
447 ULongConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
448 ::= ULONG NUMBER{ return context->MakeULongValue(context->GetULongType(), ParseULong(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
449 ;
450
451 FloatConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
452 ::= FLOAT NUMBER{ return context->MakeFloatValue(context->GetFloatType(), ParseFloat(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
453 ;
454
455 DoubleConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.ConstantValue*
456 ::= DOUBLE NUMBER{ return context->MakeDoubleValue(context->GetDoubleType(), ParseDouble(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
457 ;
458
459 ArrayConstant(cmsx.intermediate.Context* context, var cmsx.intermediate.ArrayValue* value) : cmsx.intermediate.ArrayValue*
460 ::= (LBRACKET{ value = context->MakeArrayValue(); } (Constant(context):element{ value->AddElement(element); } % COMMA)? RBRACKET){ return value; }
461 ;
462
463 StructureConstant(cmsx.intermediate.Context* context, var cmsx.intermediate.StructureValue* value) : cmsx.intermediate.StructureValue*
464 ::= LBRACE{ value = context->MakeStructureValue(); } (Constant(context):member{ value->AddMember(member); } % COMMA)? RBRACE!{ return value; }
465 ;
466
467 StringConstant(cmsx.intermediate.Context* context) : cmsx.intermediate.StringValue*
468 ::= STRING{ return context->MakeStringValue(ToUtf8(lexer.GetToken(pos).match.ToString())); }
469 ;
470
471 StringArrayConstant(cmsx.intermediate.Context* context, var cmsx.intermediate.StringArrayValue* value) : cmsx.intermediate.StringArrayValue*
472 ::= StringArrayPrefix:prefix LBRACKET{ value = context->MakeStringArrayValue(prefix); } (Constant(context):element{ value->AddElement(element); } % COMMA)? RBRACKET{ return value; }
473 ;
474
475 StringArrayPrefix : char
476 ::= ID{ string p = ToUtf8(lexer.GetToken(pos).match.ToString()); pass = p == "w" || p == "u" || p == "b"; if (pass) return p[0]; }
477 ;
478
479 Metadata(cmsx.intermediate.Context* context, var cmsx.intermediate.MDStruct* mdStruct)
480 ::= METADATA LBRACE! (MDStruct(context):mds{ mdStruct = mds; })* RBRACE!
481 ;
482
483 MDItem(cmsx.intermediate.Context* context) : cmsx.intermediate.MDItem*
484 ::= MDBool(context):mdBool{ return mdBool; }
485 | MDLong(context):mdLong{ return mdLong; }
486 | MDString(context):mdString{ return mdString; }
487 | MDStructRef(context):mdStructRef{ return mdStructRef; }
488 ;
489
490 MDBool(cmsx.intermediate.Context* context) : cmsx.intermediate.MDBool*
491 ::= TRUE{ return context->CreateMDBool(true); }
492 | FALSE{ return context->CreateMDBool(false); }
493 ;
494
495 MDLong(cmsx.intermediate.Context* context) : cmsx.intermediate.MDLong*
496 ::= NUMBER{ return context->CreateMDLong(ParseLong(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
497 ;
498
499 MDString(cmsx.intermediate.Context* context) : cmsx.intermediate.MDString*
500 ::= STRING{ return context->CreateMDString(ToUtf8(lexer.GetToken(pos).match.ToString())); }
501 ;
502
503 MDStructRef(cmsx.intermediate.Context* context) : cmsx.intermediate.MDStructRef*
504 ::= EXCLAMATION NUMBER{ return context->CreateMDStructRef(ParseInt(ToUtf8(lexer.GetToken(pos).match.ToString()))); }
505 ;
506
507 MDStruct(cmsx.intermediate.Context* context, var cmsx.intermediate.MDStruct* value) : cmsx.intermediate.MDStruct*
508 ::= (EXCLAMATION NUMBER{ value = context->CreateMDStruct(ParseInt(ToUtf8(lexer.GetToken(pos).match.ToString()))); } ASSIGN LBRACE (MDField(context, value):field % COMMA)? RBRACE){ return value; }
509 ;
510
511 MDField(cmsx.intermediate.Context* context, cmsx.intermediate.MDStruct* parent, var string fieldName)
512 ::= (ID{ fieldName = ToUtf8(lexer.GetToken(pos).match.ToString()); } COLON MDItem(context):item){ parent->AddItem(fieldName, item); }
513 ;
514 }