private void CompileBlock(GMLToken _tok) { foreach (GMLToken child in _tok.Children) { CompileStatement(child); } }
private void CompileExpression(GMLToken _tok) { EmitDebugInfo(_tok); switch (_tok.Token) { case eToken.eConstant: CompileConstant(_tok); break; case eToken.eBinary: CompileBinary(_tok); break; case eToken.eUnary: CompileUnary(_tok); break; case eToken.eFunction: CompileFunction(_tok); break; case eToken.eVariable: case eToken.eDot: CompileVariable(_tok); break; } }
private static eType CompileUnary(GMLToken _tok, TextWriter _sw) { eType result = eType.eGMLT_Unknown; switch (_tok.Id) { case 203: _sw.Write("!("); if (CompileExpression(_tok.Children[0], _sw) != 0) { _sw.Write(" > 0.5)"); } else { _sw.Write(")"); } result = eType.eGMLT_Bool; break; case 210: case 211: case 220: _sw.Write(_tok.Text); result = CompileExpression(_tok.Children[0], _sw); break; } return(result); }
private void CompileRepeat(GMLToken _tok) { VMLabel vMLabel = new VMLabel("End", VMB); VMLabel vMLabel2 = new VMLabel("Repeat", VMB); CompileExpression(_tok.Children[0]); eVM_Type eVM_Type = TypeStack.Pop(); if (eVM_Type != eVM_Type.eVMT_Int) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int); } Emit(eVM_Instruction.eVMI_DUP, eVM_Type.eVMT_Int); EmitI(eVM_Instruction.eVMI_PUSH, 0); Emit(eVM_Instruction.eVMI_SET_LE, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int); Emit(eVM_Instruction.eVMI_BTRUE, vMLabel); LoopEnv.Push(vMLabel2); LoopEndEnv.Push(vMLabel); vMLabel2.Mark(VMB.Buffer.Position); CompileStatement(_tok.Children[1]); EmitI(eVM_Instruction.eVMI_PUSH, 1); Emit(eVM_Instruction.eVMI_SUB, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int); Emit(eVM_Instruction.eVMI_DUP, eVM_Type.eVMT_Int); Emit(eVM_Instruction.eVMI_CONV, eVM_Type.eVMT_Int, eVM_Type.eVMT_Bool); Emit(eVM_Instruction.eVMI_BTRUE, vMLabel2); vMLabel.Mark(VMB.Buffer.Position); Emit(eVM_Instruction.eVMI_POPNULL, eVM_Type.eVMT_Int); LoopEnv.Pop(); LoopEndEnv.Pop(); }
private static void CompileGlobalVar(GMLToken _tok, TextWriter _sw) { foreach (GMLToken child in _tok.Children) { ms_globals[child.Text] = child.Text; } }
private static eType CompileExpression(GMLToken _tok, TextWriter _sw) { eType result = eType.eGMLT_Unknown; bool _setFunc = false; switch (_tok.Token) { case eToken.eConstant: result = CompileConstant(_tok, _sw); break; case eToken.eBinary: result = CompileBinary(_tok, _sw); break; case eToken.eUnary: result = CompileUnary(_tok, _sw); break; case eToken.eFunction: result = CompileFunction(_tok, _sw); break; case eToken.eVariable: case eToken.eDot: result = CompileVariable(_tok, _sw, false, out _setFunc); break; } return(result); }
private GMLToken RewriteTree(GMLToken _tok) { GMLToken result = null; bool flag = true; switch (_tok.Token) { case eToken.eDot: result = RewriteDot(_tok); flag = false; break; case eToken.eVariable: result = RewriteVariable(_tok); flag = false; break; } if (flag) { for (int i = 0; i < _tok.Children.Count; i++) { GMLToken gMLToken = RewriteTree(_tok.Children[i]); if (gMLToken != null) { _tok.Children[i] = gMLToken; } } } return(result); }
private GMLToken RewriteDot(GMLToken _tok) { GMLToken gMLToken = null; if (_tok.Children.Count > 2) { gMLToken = new GMLToken(_tok); GMLToken gMLToken2 = gMLToken; gMLToken2.Children = new List <GMLToken>(2); gMLToken2.Children.Add(null); gMLToken2.Children.Add(null); gMLToken2.Children[1] = _tok.Children[_tok.Children.Count - 1]; for (int num = _tok.Children.Count - 2; num > 2; num--) { gMLToken2.Children[0] = new GMLToken(_tok); gMLToken2.Children[0].Children = new List <GMLToken>(2); gMLToken2.Children[0].Children.Add(null); gMLToken2.Children[0].Children.Add(null); gMLToken2.Children[0].Children[1] = _tok.Children[num]; gMLToken2 = gMLToken2.Children[0]; } gMLToken2.Children[0] = new GMLToken(_tok); gMLToken2.Children[0].Children = new List <GMLToken>(2); gMLToken2.Children[0].Children.Add(null); gMLToken2.Children[0].Children.Add(null); gMLToken2.Children[0].Children[1] = _tok.Children[1]; gMLToken2.Children[0].Children[0] = _tok.Children[0]; } return(gMLToken); }
public GMLError(eErrorKind _kind, string _error, GMLToken _token, params object[] _others) { Kind = _kind; Error = _error; Token = _token; Params = new List <object>(_others); }
private static void CompileReturn(GMLToken _tok, TextWriter _sw) { _sw.Write("return "); if (_tok.Children.Count > 0) { CompileExpression(_tok.Children[0], _sw); } }
public GMLToken(eToken _tok, GMLToken _pass1, int _id, GMLValue _value) { Token = _tok; Index = _pass1.Index; Text = _pass1.Text; Id = _id; Value = new GMLValue(_value); Children = new List <GMLToken>(); }
private void CompilePop(GMLToken _tok, eVM_Type _type) { switch (_tok.Token) { case eToken.eVariable: case eToken.eDot: if (_tok.Children.Count >= 2) { int num = 0; CompileExpression(_tok.Children[0]); if (TypeStack.Peek() != eVM_Type.eVMT_Int) { Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); } if (_tok.Children[1].Children.Count > 0) { CompileExpression(_tok.Children[1].Children[0]); if (TypeStack.Peek() != eVM_Type.eVMT_Int) { Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); } if (_tok.Children[1].Children.Count > 1) { EmitI(eVM_Instruction.eVMI_PUSH, 32000); Emit(eVM_Instruction.eVMI_MUL, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int); CompileExpression(_tok.Children[1].Children[1]); if (TypeStack.Peek() != eVM_Type.eVMT_Int) { Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); } Emit(eVM_Instruction.eVMI_ADD, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int); TypeStack.Pop(); } TypeStack.Pop(); } else { num |= int.MinValue; } TypeStack.Pop(); EmitIVar(eVM_Instruction.eVMI_POP, _tok.Children[1].Id | num, _type); TypeStack.Push(eVM_Type.eVMT_Variable); } else { Error("Malformed variable reference", _tok); } break; case eToken.eConstant: Error("Unsure where these come from", _tok); break; } }
public GMLToken(GMLToken _tok) { Token = _tok.Token; Index = _tok.Index; Text = _tok.Text; Id = _tok.Id; Value = new GMLValue(_tok.Value); Children = new List <GMLToken>(_tok.Children); }
private GMLToken RewriteVariable(GMLToken _tok) { GMLToken gMLToken = new GMLToken(_tok); gMLToken.Token = eToken.eDot; gMLToken.Children = new List <GMLToken>(2); gMLToken.Children.Add(new GMLToken(eToken.eConstant, _tok, -6, new GMLValue(-6.0))); gMLToken.Children.Add(_tok); return(gMLToken); }
private static void CompileBlock(GMLToken _tok, TextWriter _sw) { _sw.WriteLine("{"); foreach (GMLToken child in _tok.Children) { CompileStatement2(child, _sw); _sw.WriteLine(";"); } _sw.WriteLine("}"); }
private static void CompileWith(GMLToken _tok, TextWriter _sw) { if (_tok.Children.Count != 2) { Error("malformed with statement", _tok); } if (_tok.Children[0].Token == eToken.eConstant && (_tok.Children[0].Text == "other" || _tok.Children[0].Text == "self")) { string item = string.Empty; switch (_tok.Children[0].Text) { case "other": item = ms_otherName.Peek(); break; case "self": item = ms_thisName.Peek(); break; } ms_otherName.Push(ms_thisName.Peek()); ms_thisName.Push(item); CompileStatement(_tok.Children[1], _sw); if (_tok.Children[1].Token != eToken.eBegin) { _sw.Write(";"); } ms_thisName.Pop(); ms_otherName.Pop(); return; } _sw.WriteLine("{"); string uniqueName = GetUniqueName(); string uniqueName2 = GetUniqueName(); string uniqueName3 = GetUniqueName(); _sw.Write("var {0} = GetWithArray(", uniqueName); CompileExpression(_tok.Children[0], _sw); _sw.WriteLine(" );"); _sw.WriteLine("for( var {0} in {1} ) {{", uniqueName2, uniqueName); _sw.WriteLine(" var {0} = {1}[{2}];", uniqueName3, uniqueName, uniqueName2); ms_otherName.Push(ms_thisName.Peek()); ms_thisName.Push(uniqueName3); ms_statements++; ms_breakContext.Push("CompileWith"); CompileStatement(_tok.Children[1], _sw); ms_breakContext.Pop(); if (_tok.Children[1].Token != eToken.eBegin) { _sw.Write(";"); } _sw.WriteLine("}"); ms_thisName.Pop(); ms_otherName.Pop(); _sw.WriteLine("}"); }
private void BinaryTypeCoercion(GMLToken _tok, int _parmNum) { eVM_Type eVM_Type = TypeStack.Peek(); switch (_tok.Children[1].Token) { case eToken.eNot: case eToken.eLess: case eToken.eLessEqual: case eToken.eEqual: case eToken.eNotEqual: case eToken.eGreaterEqual: case eToken.eGreater: case eToken.eBitNegate: break; case eToken.ePlus: case eToken.eMinus: case eToken.eTime: case eToken.eDivide: case eToken.eDiv: case eToken.eMod: if (eVM_Type == eVM_Type.eVMT_Bool) { TypeStack.Pop(); Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); } break; case eToken.eAnd: case eToken.eOr: case eToken.eXor: if (eVM_Type != eVM_Type.eVMT_Bool) { TypeStack.Pop(); Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Bool); TypeStack.Push(eVM_Type.eVMT_Bool); } break; case eToken.eBitOr: case eToken.eBitAnd: case eToken.eBitXor: case eToken.eBitShiftLeft: case eToken.eBitShiftRight: if (eVM_Type == eVM_Type.eVMT_Int) { TypeStack.Pop(); Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); } break; } }
private void CompileUnary(GMLToken _tok) { CompileExpression(_tok.Children[0]); eVM_Type eVM_Type = TypeStack.Peek(); switch (_tok.Id) { case 203: switch (eVM_Type) { case eVM_Type.eVMT_String: case eVM_Type.eVMT_Error: Error("Unable to Not a string", _tok); break; case eVM_Type.eVMT_Double: case eVM_Type.eVMT_Float: case eVM_Type.eVMT_Int: case eVM_Type.eVMT_Long: case eVM_Type.eVMT_Variable: TypeStack.Pop(); Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Bool); TypeStack.Push(eVM_Type.eVMT_Bool); eVM_Type = eVM_Type.eVMT_Bool; break; } Emit(eVM_Instruction.eVMI_NOT, eVM_Type); break; case 211: Emit(eVM_Instruction.eVMI_NEG, eVM_Type); break; case 220: switch (eVM_Type) { case eVM_Type.eVMT_String: case eVM_Type.eVMT_Error: Error("Unable to Negate a string", _tok); break; case eVM_Type.eVMT_Double: case eVM_Type.eVMT_Float: case eVM_Type.eVMT_Variable: TypeStack.Pop(); Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); eVM_Type = eVM_Type.eVMT_Int; break; } Emit(eVM_Instruction.eVMI_NOT, eVM_Type); break; } }
private static void CompileContinue(GMLToken _tok, TextWriter _sw) { if (ms_breakContext.Count > 0) { _sw.Write("continue"); } else { _sw.Write("return"); } }
private static void CompileSwitch(GMLToken _tok, TextWriter _sw) { if (_tok.Children.Count == 0) { Error("malformed switch statement", _tok); } _sw.Write("switch("); CompileExpression(_tok.Children[0], _sw); _sw.WriteLine(") {"); ms_breakContext.Push("CompileSwitch"); bool flag = false; for (int i = 1; i < _tok.Children.Count; i++) { switch (_tok.Children[i].Token) { case eToken.eCase: _sw.Write("case "); CompileExpression(_tok.Children[i].Children[0], _sw); _sw.WriteLine(":"); flag = true; break; case eToken.eDefault: _sw.WriteLine("default:"); flag = true; break; case eToken.eBreak: if (!flag) { Error("statement in a switch MUST appear after case or default", _tok.Children[i]); break; } CompileStatement(_tok.Children[i], _sw); _sw.WriteLine(";"); flag = false; break; default: if (!flag) { Error("statement in a switch MUST appear after case or default", _tok.Children[i]); break; } CompileStatement(_tok.Children[i], _sw); _sw.WriteLine(";"); break; } } _sw.Write("}"); ms_breakContext.Pop(); }
private static eType CompileConstant(GMLToken _tok, TextWriter _sw) { bool _setFunc = false; eType result = eType.eGMLT_Var; switch (_tok.Text) { case "global": case "other": case "self": CompileVariable(_tok, _sw, false, out _setFunc); break; default: switch (_tok.Value.Kind) { case eKind.eConstant: _sw.Write("g_gmlConst.{0}", _tok.Value.ValueS); break; case eKind.eNone: _sw.Write("null"); break; case eKind.eNumber: if (_tok.Value.ValueI < 0.0) { _sw.Write("("); } _sw.Write("{0}", Convert.ToString(_tok.Value.ValueI, CultureInfo.InvariantCulture.NumberFormat)); if (_tok.Value.ValueI < 0.0) { _sw.Write(")"); } result = ((!(_tok.Text == "true") && !(_tok.Text == "false")) ? eType.eGMLT_Real : eType.eGMLT_Bool); break; case eKind.eString: { string text = _tok.Value.ValueS.Replace("\\", "\\\\"); text = text.Replace("\"", "\\\""); text = text.Replace(Environment.NewLine, "#"); text = text.Replace(new string('\n', 1), "#"); _sw.Write("\"{0}\"", text); result = eType.eGMLT_String; break; } } break; } return(result); }
private static void CompileAssign(GMLToken _tok, TextWriter _sw) { if (_tok.Children.Count != 3) { Error("malformed assignment statement", _tok); } bool _setFunc = false; CompileVariable(_tok.Children[0], _sw, true, out _setFunc); if (!_setFunc) { switch (_tok.Children[1].Token) { case eToken.eAssignPlus: case eToken.eAssignMinus: case eToken.eAssignTimes: case eToken.eAssignDivide: case eToken.eAssignOr: case eToken.eAssignAnd: case eToken.eAssignXor: _sw.Write(_tok.Children[1].Text); CompileExpression(_tok.Children[2], _sw); break; case eToken.eAssign: _sw.Write("="); CompileExpression(_tok.Children[2], _sw); break; } return; } switch (_tok.Children[1].Token) { case eToken.eAssignPlus: case eToken.eAssignMinus: case eToken.eAssignTimes: case eToken.eAssignDivide: case eToken.eAssignOr: case eToken.eAssignAnd: case eToken.eAssignXor: CompileVariable(_tok.Children[0], _sw, false, out _setFunc); _sw.Write(" {0} ", _tok.Children[1].Text[0]); CompileExpression(_tok.Children[2], _sw); break; case eToken.eAssign: CompileExpression(_tok.Children[2], _sw); break; } _sw.Write(" )"); }
private void CompileFunction(GMLToken _tok) { foreach (GMLToken child in _tok.Children) { CompileExpression(child); eVM_Type eVM_Type = TypeStack.Pop(); if (eVM_Type != eVM_Type.eVMT_Variable) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Variable); } } EmitI(eVM_Instruction.eVMI_CALL, _tok.Id); TypeStack.Push(GMAssetCompiler.eVM_Type.eVMT_Variable); }
private static void CompileDo(GMLToken _tok, TextWriter _sw) { if (_tok.Children.Count != 2) { Error("malformed do statement", _tok); } _sw.WriteLine("do {"); ms_breakContext.Push("CompileDo"); CompileStatement(_tok.Children[0], _sw); ms_breakContext.Pop(); _sw.Write("} while( !("); CompileExpression(_tok.Children[1], _sw); _sw.WriteLine("))"); }
private void CompileConstant(GMLToken _tok) { switch (_tok.Value.Kind) { case eKind.eConstant: Error("constant token", _tok); break; case eKind.eNone: Error("None constant token", _tok); break; case eKind.eNumber: { double num = (long)_tok.Value.ValueI; if (num == _tok.Value.ValueI) { long num2 = (long)_tok.Value.ValueI; if (num2 > int.MaxValue || num2 < int.MinValue) { EmitI(eVM_Instruction.eVMI_PUSH, num2); TypeStack.Push(eVM_Type.eVMT_Long); } else if (num2 > 32767 || num2 < -32768) { EmitI(eVM_Instruction.eVMI_PUSH, (int)num2); TypeStack.Push(eVM_Type.eVMT_Int); } else { VMB.Add(VMBuffer.EncodeInstructionArg(192, 15) | (int)(num2 & 0xFFFF)); TypeStack.Push(eVM_Type.eVMT_Int); } } else { EmitI(eVM_Instruction.eVMI_PUSH, _tok.Value.ValueI); TypeStack.Push(eVM_Type.eVMT_Double); } break; } case eKind.eString: EmitI(eVM_Instruction.eVMI_PUSH, _tok.Value.ValueS); TypeStack.Push(eVM_Type.eVMT_String); break; } }
private void CompileProgram(GMLToken _tok) { switch (_tok.Token) { case eToken.eEOF: break; case eToken.eBlock: CompileBlock(_tok); break; default: Error("No program to compile", _tok); break; } }
private static void CompileProgram(GMLToken _tok, TextWriter _sw) { switch (_tok.Token) { case eToken.eEOF: break; case eToken.eBlock: CompileBlock(_tok, _sw); break; default: Error("No program to compile", _tok); break; } }
private static void CompileWhile(GMLToken _tok, TextWriter _sw) { if (_tok.Children.Count != 2) { Error("malformed while statement", _tok); } _sw.Write("while ("); CompileExpression(_tok.Children[0], _sw); _sw.Write(") "); ms_breakContext.Push("CompileWhile"); if (_tok.Children[1].Token == eToken.eBegin) { ms_statements++; } CompileStatement(_tok.Children[1], _sw); ms_breakContext.Pop(); }
public static void Error(string _errorMessage, GMLToken _token) { if (!Program.InhibitErrorOutput) { int num = 1; for (int i = 0; i < _token.Index; i++) { if (ms_code.Code[i] == '\n') { num++; } } Console.WriteLine("Error : {0}({1}) : {2}", ms_code.Name, num, _errorMessage); } ms_numErrors++; ms_error = true; Program.ExitCode = 1; }
private static void CompileRepeat(GMLToken _tok, TextWriter _sw) { if (_tok.Children.Count != 2) { Error("malformed repeat statement", _tok); } string uniqueName = GetUniqueName(); string uniqueName2 = GetUniqueName(); _sw.Write("for( var {0}=0, {1}=", uniqueName, uniqueName2); CompileExpression(_tok.Children[0], _sw); _sw.Write("; {0}<{1}; {0}++) ", uniqueName, uniqueName2); if (_tok.Children[1].Token == eToken.eBegin) { ms_statements++; } ms_breakContext.Push("CompileRepeat"); CompileStatement(_tok.Children[1], _sw); ms_breakContext.Pop(); }