public override string GenCode() { var type = Compiler.GetVariable(Name); Compiler.EmitCode("call string [mscorlib]System.Console::ReadLine()"); switch (type) { case ValType.Int: Compiler.EmitCode("call int32 [mscorlib]System.Int32::Parse(string)"); break; case ValType.Double: Compiler.EmitCode("call class [mscorlib]System.Globalization.CultureInfo [mscorlib]System.Globalization.CultureInfo::get_InvariantCulture()"); Compiler.EmitCode("call float64 [mscorlib]System.Double::Parse(string, class [mscorlib]System.IFormatProvider)"); break; case ValType.Bool: Compiler.EmitCode("call bool [mscorlib]System.Boolean::Parse(string)"); break; default: Compiler.AddError(new UndefinedRuntimeError(LineNo)); break; } Compiler.EmitCode($"stloc _{Name}"); return(""); }
public override string GenCode() { string text = ""; switch (Type) { case ValType.Int: text = $".locals init ( int32 _{Name} )"; break; case ValType.Double: text = $".locals init ( float64 _{Name} )"; break; case ValType.Bool: text = $".locals init ( int32 _{Name} )"; break; default: Compiler.AddError(new UndefinedRuntimeError(LineNo)); return(text); } Compiler.EmitCode(text, false); return(text); }
public override string GenCode() { Child?.GenCode(); string text = ""; switch (OperatorType) { case OpType.Minus: text = "neg"; break; case OpType.BitNot: text = "not"; break; case OpType.LogNot: // Create fake node with const 1 // Add it to stack and call bit xor with old stack top var helperNode = new ConstantNode(-1, ValType.Bool, true); helperNode.GenCode(); text = "xor"; break; case OpType.IntCast: text = "conv.i4"; break; case OpType.DoubleCast: text = "conv.r8"; break; default: Compiler.AddError(new UndefinedRuntimeError(LineNo)); break; } Compiler.EmitCode(text); if (GenPop) { Compiler.EmitCode("pop", true); } return(text); }
public override string GenCode() { if (Text != null) { Compiler.EmitCode($"ldstr {Text}"); Compiler.EmitCode($"call void [mscorlib]System.Console::Write(string)"); } else { switch (ExpressionNode.Type) { case ValType.Int: ExpressionNode.GenCode(); Compiler.EmitCode($"call void [mscorlib]System.Console::Write(int32)"); break; case ValType.Double: Compiler.EmitCode($"call class [mscorlib]System.Globalization.CultureInfo [mscorlib]System.Globalization.CultureInfo::get_InvariantCulture()"); Compiler.EmitCode("ldstr \"{0:0.000000}\""); ExpressionNode.GenCode(); Compiler.EmitCode("box [mscorlib]System.Double"); Compiler.EmitCode("call string [mscorlib]System.String::Format(class [mscorlib]System.IFormatProvider, string, object)"); Compiler.EmitCode("call void [mscorlib]System.Console::Write(string)"); break; case ValType.Bool: ExpressionNode.GenCode(); Compiler.EmitCode($"call void [mscorlib]System.Console::Write(bool)"); break; default: Compiler.AddError(new UndefinedRuntimeError(LineNo)); break; } } return(""); }
public override string GenCode() { // Implicit cast int -> double // Generate fake node with explicit cast SyntaxTreeNode tempNode; if (Left.Type == ValType.Int && Right.Type == ValType.Double) { tempNode = new UnaryOperationNode(LineNo, ValType.Double, OpType.DoubleCast, Left); Left = tempNode; } else if (Left.Type == ValType.Double && Right.Type == ValType.Int) { tempNode = new UnaryOperationNode(LineNo, ValType.Double, OpType.DoubleCast, Right); Right = tempNode; } // Optimize calculations in those cases - done in switch below if (OperatorType != OpType.LogOr && OperatorType != OpType.LogAnd) { Left?.GenCode(); Right?.GenCode(); } string text = ""; var helperNode = new UnaryOperationNode(-1, ValType.Bool, OpType.LogNot, null); switch (OperatorType) { case OpType.LogOr: var falseLabel = Compiler.GenerateLabel(); var trueLabel = Compiler.GenerateLabel(); var endLabel = Compiler.GenerateLabel(); Left.GenCode(); Compiler.EmitCode($"brtrue {trueLabel}"); Right.GenCode(); Compiler.EmitCode($"brtrue {trueLabel}"); Compiler.EmitCode("ldc.i4.0", true, falseLabel); Compiler.EmitCode($"br {endLabel}"); Compiler.EmitCode("ldc.i4.1", true, trueLabel); Compiler.EmitCode("nop", true, endLabel); break; case OpType.LogAnd: falseLabel = Compiler.GenerateLabel(); trueLabel = Compiler.GenerateLabel(); endLabel = Compiler.GenerateLabel(); Left.GenCode(); Compiler.EmitCode($"brfalse {falseLabel}"); Right.GenCode(); Compiler.EmitCode($"brtrue {trueLabel}"); Compiler.EmitCode("ldc.i4.0", true, falseLabel); Compiler.EmitCode($"br {endLabel}"); Compiler.EmitCode("ldc.i4.1", true, trueLabel); Compiler.EmitCode("nop", true, endLabel); break; case OpType.Equal: text = "ceq"; break; case OpType.NotEqual: // Check for equality // And negate stack top (equality result) Compiler.EmitCode("ceq"); helperNode.GenCode(); break; case OpType.Greater: text = "cgt"; break; case OpType.GreaterOrEqual: // Check for less // And negate stack top (less result) Compiler.EmitCode("clt"); helperNode.GenCode(); break; case OpType.Less: text = "clt"; break; case OpType.LessOrEqual: // Check for greater // And negate stack top (greater result) Compiler.EmitCode("cgt"); helperNode.GenCode(); break; case OpType.Plus: text = "add"; break; case OpType.Minus: text = "sub"; break; case OpType.Multiply: text = "mul"; break; case OpType.Divide: text = "div"; break; case OpType.BitOr: text = "or"; break; case OpType.BitAnd: text = "and"; break; default: Compiler.AddError(new UndefinedRuntimeError(LineNo)); break; } Compiler.EmitCode(text); if (GenPop) { Compiler.EmitCode("pop", true); } return(text); }