예제 #1
0
    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("");
    }
예제 #2
0
    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);
    }
예제 #3
0
    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);
    }
예제 #4
0
    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("");
    }
예제 #5
0
    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);
    }