예제 #1
0
        public override void TranslateOpChain(StringBuilder sb, OpChain opChain)
        {
            if (opChain.Expressions.Length == 2)
            {
                // Avoid parenthesis. Extraneous parenthesis are actually warnings in C for these operators.
                switch (opChain.Ops[0].Value)
                {
                case "==":
                case "!=":
                case ">":
                case "<":
                case "<=":
                case ">=":
                    this.TranslateExpression(sb, opChain.Expressions[0]);
                    sb.Append(' ');
                    sb.Append(opChain.Ops[0].Value);
                    sb.Append(' ');
                    this.TranslateExpression(sb, opChain.Expressions[1]);
                    return;

                default: break;
                }
            }
            base.TranslateOpChain(sb, opChain);
        }
예제 #2
0
        private Expression ParseExponents(TokenStream tokens, Node owner)
        {
            Expression expr = ParseIncrement(tokens, owner);
            string     next = tokens.PeekValue();

            if (next == "**")
            {
                Token      op    = tokens.Pop();
                Expression right = ParseNegate(tokens, owner);
                expr = new OpChain(expr, op, right, owner);
            }
            return(expr);
        }
예제 #3
0
        private Expression ParseMultiplication(TokenStream tokens, Node owner)
        {
            Expression expr = ParseNegate(tokens, owner);
            string     next = tokens.PeekValue();

            while (MULTIPLICATION_OPS.Contains(next))
            {
                Token      op    = tokens.Pop();
                Expression right = ParseNegate(tokens, owner);
                expr = new OpChain(expr, op, right, owner);
                next = tokens.PeekValue();
            }
            return(expr);
        }
예제 #4
0
        private IfStatement BuildIfStatement(int id, string op, Executable[] trueCode, Executable[] falseCode)
        {
            Pastel.Token equalsToken = Pastel.Token.CreateDummyToken(op);
            Variable     variable    = new Variable(Pastel.Token.CreateDummyToken(this.ConditionVariableName));

            variable.ApplyPrefix = false;
            Expression condition = new OpChain(new Expression[] { variable, InlineConstant.Of(id) }, new Pastel.Token[] { equalsToken });

            return(new IfStatement(
                       Pastel.Token.CreateDummyToken("if"),
                       condition,
                       TrimBreak(trueCode),
                       Pastel.Token.CreateDummyToken("else"),
                       TrimBreak(falseCode)));
        }
예제 #5
0
 public override void TranslateOpChain(StringBuilder sb, OpChain opChain)
 {
     // Need to do something about these parenthesis.
     sb.Append('(');
     for (int i = 0; i < opChain.Expressions.Length; ++i)
     {
         if (i > 0)
         {
             sb.Append(' ');
             sb.Append(opChain.Ops[i - 1].Value);
             sb.Append(' ');
         }
         this.TranslateExpression(sb, opChain.Expressions[i]);
     }
     sb.Append(')');
 }
예제 #6
0
 public override void TranslateOpChain(StringBuilder sb, OpChain opChain)
 {
     sb.Append('(');
     Expression[]   expressions = opChain.Expressions;
     Pastel.Token[] ops         = opChain.Ops;
     for (int i = 0; i < expressions.Length; ++i)
     {
         if (i > 0)
         {
             // TODO: platform should have an op translator, which would just be a pass-through function for most ops.
             sb.Append(' ');
             sb.Append(this.TranslateOp(ops[i - 1].Value));
             sb.Append(' ');
         }
         this.TranslateExpression(sb, expressions[i]);
     }
     sb.Append(')');
 }
예제 #7
0
        public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, OpChain opChain, bool outputUsed)
        {
            if (!outputUsed)
            {
                if (opChain.OpToken.Value == "==")
                {
                    throw new ParserException(opChain.OpToken, "'==' cannot be used like this. Did you mean to use just a single '=' instead?");
                }
                throw new ParserException(opChain, "This expression isn't valid here.");
            }

            bcc.CompileExpressionList(parser, buffer, new Expression[] { opChain.Left, opChain.Right }, true);


            switch (opChain.OpTEMP)
            {
            case Ops.EQUALS:
            case Ops.NOT_EQUALS:
                buffer.Add(opChain.OpToken, OpCode.EQUALS, opChain.OpTEMP == Ops.EQUALS ? 0 : 1);
                break;

            default:
                buffer.Add(opChain.OpToken, OpCode.BINARY_OP, (int)opChain.OpTEMP);
                break;
            }

            if (!outputUsed)
            {
                buffer.Add(null, OpCode.POP);
            }
        }
예제 #8
0
 public abstract void TranslateOpChain(StringBuilder sb, OpChain opChain);
예제 #9
0
 public abstract void TranslateOpChain(TranspilerContext sb, OpChain opChain);
예제 #10
0
        public void TranslateExpression(TranspilerContext sb, Expression expression)
        {
            string typeName = expression.GetType().Name;

            switch (typeName)
            {
            case "CastExpression": this.TranslateCast(sb, ((CastExpression)expression).Type, ((CastExpression)expression).Expression); break;

            case "FunctionReference": this.TranslateFunctionReference(sb, (FunctionReference)expression); break;

            case "FunctionPointerInvocation": this.TranslateFunctionPointerInvocation(sb, (FunctionPointerInvocation)expression); break;

            case "CoreFunctionInvocation": this.TranslateCoreFunctionInvocation(sb, (CoreFunctionInvocation)expression); break;

            case "OpChain":
                OpChain oc = (OpChain)expression;
                if (oc.IsStringConcatenation)
                {
                    this.TranslateStringConcatenation(sb, oc.Expressions);
                }
                else
                {
                    this.TranslateOpChain(sb, oc);
                }
                break;

            case "ExtensibleFunctionInvocation":
                this.TranslateExtensibleFunctionInvocation(
                    sb,
                    (ExtensibleFunctionInvocation)expression);
                break;

            case "InlineIncrement":
                InlineIncrement ii = (InlineIncrement)expression;
                this.TranslateInlineIncrement(sb, ii.Expression, ii.IsPrefix, ii.IncrementToken.Value == "++");
                break;

            case "FunctionInvocation":
                FunctionInvocation funcInvocation = (FunctionInvocation)expression;
                string             prefix         = null;
                FunctionDefinition funcDef        = ((FunctionReference)funcInvocation.Root).Function;
                PastelContext      targetContext  = funcDef.Context;
                PastelContext      callerContext  = funcInvocation.Owner.Context;
                if (targetContext != callerContext)
                {
                    prefix = callerContext.GetDependencyExportPrefix(targetContext);
                }

                if (prefix != null)
                {
                    this.TranslateFunctionInvocationWithPrefix(sb, prefix, (FunctionReference)funcInvocation.Root, funcInvocation.Args);
                }
                else
                {
                    this.TranslateFunctionInvocation(sb, (FunctionReference)funcInvocation.Root, funcInvocation.Args);
                }
                break;

            case "Variable":
                Variable v = (Variable)expression;
                this.TranslateVariable(sb, v);
                break;

            case "ConstructorInvocation":
                ConstructorInvocation constructor = (ConstructorInvocation)expression;
                string rootType = constructor.Type.RootValue;
                switch (rootType)
                {
                case "Array":
                    if (constructor.Type.Generics.Length != 1)
                    {
                        throw new Pastel.ParserException(constructor.Type.FirstToken, "Array constructor requires exactly 1 generic type.");
                    }
                    this.TranslateArrayNew(sb, constructor.Type.Generics[0], constructor.Args[0]);
                    break;

                case "List":
                    if (constructor.Type.Generics.Length != 1)
                    {
                        throw new Pastel.ParserException(constructor.Type.FirstToken, "List constructor requires exactly 1 generic type.");
                    }
                    this.TranslateListNew(sb, constructor.Type.Generics[0]);
                    break;

                case "Dictionary":
                    if (constructor.Type.Generics.Length != 2)
                    {
                        throw new Pastel.ParserException(constructor.Type.FirstToken, "Dictionary constructor requires exactly 2 generic types.");
                    }
                    PType dictionaryKeyType   = constructor.Type.Generics[0];
                    PType dictionaryValueType = constructor.Type.Generics[1];
                    this.TranslateDictionaryNew(sb, dictionaryKeyType, dictionaryValueType);
                    break;

                case "StringBuilder":
                    if (constructor.Type.Generics.Length != 0)
                    {
                        throw new ParserException(constructor.Type.FirstToken, "StringBuilder constructor does not have any generics.");
                    }
                    this.TranslateStringBuilderNew(sb);
                    break;

                default:
                    // TODO: throw an exception (in the parser) if generics exist.
                    this.TranslateConstructorInvocation(sb, constructor);
                    break;
                }
                break;

            case "DotField":
                DotField         df        = (DotField)expression;
                StructDefinition structDef = df.StructType;
                ClassDefinition  classDef  = df.ClassType;
                string           fieldName = df.FieldName.Value;
                if (classDef != null)
                {
                    this.TranslateInstanceFieldDereference(sb, df.Root, classDef, fieldName);
                }
                else if (structDef != null)
                {
                    int fieldIndex = structDef.FlatFieldIndexByName[fieldName];
                    this.TranslateStructFieldDereference(sb, df.Root, structDef, fieldName, fieldIndex);
                }
                else
                {
                    throw new InvalidOperationException();     // should have been thrown by the compiler
                }
                break;

            case "InlineConstant":
                InlineConstant ic = (InlineConstant)expression;
                switch (ic.ResolvedType.RootValue)
                {
                case "bool": this.TranslateBooleanConstant(sb, (bool)ic.Value); break;

                case "char": this.TranslateCharConstant(sb, ((string)ic.Value)[0]); break;

                case "double": this.TranslateFloatConstant(sb, (double)ic.Value); break;

                case "int": this.TranslateIntegerConstant(sb, (int)ic.Value); break;

                case "null": this.TranslateNullConstant(sb); break;

                case "string": this.TranslateStringConstant(sb, (string)ic.Value); break;

                default: throw new NotImplementedException();
                }
                break;

            case "ThisExpression":
                this.TranslateThis(sb, (ThisExpression)expression);
                break;

            case "UnaryOp":
                UnaryOp uo = (UnaryOp)expression;
                if (uo.OpToken.Value == "-")
                {
                    this.TranslateNegative(sb, uo);
                }
                else
                {
                    this.TranslateBooleanNot(sb, uo);
                }
                break;

            case "ForcedParenthesis":
                sb.Append('(');
                this.TranslateExpression(sb, ((ForcedParenthesis)expression).Expression);
                sb.Append(')');
                break;

            default: throw new NotImplementedException(typeName);
            }
        }