Esempio n. 1
0
 public override void TranslateCast(StringBuilder sb, PType type, Expression expression)
 {
     if (expression is DotField)
     {
         DotField df = (DotField)expression;
         if (df.FieldName.Value == "internalValue" && df.Root.ResolvedType.RootValue == "Value")
         {
             if (df.Root is Variable)
             {
                 this.TranslateExpression(sb, df.Root);
             }
             else
             {
                 sb.Append('(');
                 this.TranslateExpression(sb, df.Root);
                 sb.Append(')');
             }
             sb.Append("->");
             sb.Append(this.GetValueStructInternalValueFieldName(type));
             return;
         }
     }
     sb.Append("((");
     sb.Append(this.Platform.TranslateType(type));
     sb.Append(")(");
     this.TranslateExpression(sb, expression);
     sb.Append("))");
 }
Esempio n. 2
0
        public override void TranslateAssignment(StringBuilder sb, Assignment assignment)
        {
            DotField df = assignment.Target as DotField;

            if (df != null && df.FieldName.Value == "internalValue" && df.Root.ResolvedType.RootValue == "Value")
            {
                bool isVar = df.Root is Variable;
                if (!isVar)
                {
                    sb.Append('(');
                }
                this.TranslateExpression(sb, df.Root);
                if (!isVar)
                {
                    sb.Append(')');
                }
                sb.Append("->");
                sb.Append(this.GetValueStructInternalValueFieldName(assignment.Value.ResolvedType));
                sb.Append(' ');
                sb.Append(assignment.OpToken.Value);
                sb.Append(' ');
                this.TranslateExpression(sb, assignment.Value);
                sb.Append(';');
                sb.Append(this.NewLine);
            }
            else
            {
                base.TranslateAssignment(sb, assignment);
            }
        }
Esempio n. 3
0
 public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, DotField dotField, bool outputUsed)
 {
     CompileImpl(bcc, parser, buffer, dotField.Root, dotField.DotToken, dotField.FieldToken, outputUsed);
 }
Esempio n. 4
0
        public override void TranslateCast(TranspilerContext sb, PType type, Expression expression)
        {
            DotField dotField = expression as DotField;

            if (dotField != null &&
                dotField.Root.ResolvedType.RootValue == "Value" &&
                dotField.FieldName.Value == "internalValue")
            {
                if (type.RootValue == "int")
                {
                    this.TranslateExpression(sb, dotField.Root);
                    sb.Append(".intValue");
                    return;
                }
                else if (type.RootValue == "bool")
                {
                    sb.Append('(');
                    this.TranslateExpression(sb, dotField.Root);
                    sb.Append(".intValue == 1)");
                    return;
                }
            }

            sb.Append('(');
            if (this.isJava6) // "(int) object" vs "(Integer) object"
            {
                string castRootType = this.TranslateType(type);
                if (expression is CastExpression)
                {
                    CastExpression ce        = (CastExpression)expression;
                    string         outerType = castRootType;
                    string         innerType = this.TranslateType(expression.ResolvedType);

                    if ((outerType == "int" || outerType == "double") &&
                        (innerType == "int" || innerType == "double"))
                    {
                        switch (outerType + "+" + innerType)
                        {
                        case "int+double":
                            sb.Append("(int) (double) (Double) ");
                            this.TranslateExpression(sb, ce.Expression);
                            sb.Append(')');
                            return;

                        case "double+int":
                            sb.Append("(double) (int) (Integer) ");
                            this.TranslateExpression(sb, ce.Expression);
                            sb.Append(')');
                            return;

                        default:
                            break;
                        }
                    }
                }

                switch (castRootType)
                {
                case "bool":
                case "int":
                case "double":
                case "char":
                    sb.Append('(');
                    sb.Append(this.TranslateType(type));
                    sb.Append(") (");
                    sb.Append(this.TranslateJavaNestedType(type));
                    sb.Append(") ");
                    this.TranslateExpression(sb, expression);
                    sb.Append(')');
                    return;

                default:
                    break;
                }
            }
            sb.Append('(');
            sb.Append(this.TranslateType(type));
            sb.Append(") ");

            this.TranslateExpression(sb, expression);
            sb.Append(')');
        }
Esempio n. 5
0
        private static Expression ParseAtomWithSuffix(ParserContext context, TokenStream tokens, TopLevelEntity parent)
        {
            Expression root;

            if (tokens.IsNext("("))
            {
                Token openParen = tokens.Pop();

                switch (IdentifyParenthesisSituation(tokens))
                {
                case ParenthesisSituation.CAST:
                    CSharpType castType = CSharpType.Parse(tokens);
                    tokens.PopExpected(")");
                    Expression castValue = ParseAtomWithSuffix(context, tokens, parent);
                    return(new CastExpression(openParen, castType, castValue, parent));

                case ParenthesisSituation.LAMBDA_ARG:
                    List <Token> lambdaArgs = new List <Token>()
                    {
                        tokens.PopWord()
                    };

                    while (tokens.PopIfPresent(","))
                    {
                        lambdaArgs.Add(tokens.PopWord());
                    }
                    tokens.PopExpected(")");
                    Token        arrowToken = tokens.PopExpected("=>");
                    Executable[] lambdaBody;
                    if (tokens.IsNext("{"))
                    {
                        lambdaBody = ExecutableParser.ParseCodeBlock(context, tokens, parent, true);
                    }
                    else
                    {
                        Expression expr = Parse(context, tokens, parent);
                        lambdaBody = new Executable[] {
                            new ReturnStatement(expr.FirstToken, expr, parent)
                        };
                    }
                    return(new Lambda(openParen, lambdaArgs, arrowToken, lambdaBody, parent));

                case ParenthesisSituation.WRAPPED_EXPRESSION:
                    root = Parse(context, tokens, parent);
                    tokens.PopExpected(")");
                    break;

                default:
                    throw new Exception();     // not valid
                }
            }
            else
            {
                root = ParseAtom(context, tokens, parent);
            }
            bool   anythingInteresting = true;
            string next = tokens.PeekValue();

            while (anythingInteresting)
            {
                switch (next)
                {
                case ".":
                    Token dotToken  = tokens.Pop();
                    Token fieldName = tokens.PopWord();
                    root = new DotField(root.FirstToken, root, dotToken, fieldName, parent);
                    break;

                case "[":
                    Token      openBracket = tokens.Pop();
                    Expression index       = Parse(context, tokens, parent);
                    tokens.PopExpected("]");
                    root = new BracketIndex(root, openBracket, index, parent);
                    break;

                case "<":
                    if (root is DotField)
                    {
                        CSharpType[] functionInvocationTypeSpecification = MaybeParseOutOneOfThoseInlineTypeSpecificationsForFunctionInvocations(tokens);
                        if (functionInvocationTypeSpecification != null)
                        {
                            ((DotField)root).InlineTypeSpecification = functionInvocationTypeSpecification;
                        }
                        else
                        {
                            anythingInteresting = false;
                        }
                    }
                    else
                    {
                        anythingInteresting = false;
                    }
                    break;

                case "(":
                    Token             openParen = tokens.Pop();
                    List <Expression> args      = new List <Expression>();
                    List <Token>      outTokens = new List <Token>();
                    while (!tokens.PopIfPresent(")"))
                    {
                        if (args.Count > 0)
                        {
                            tokens.PopExpected(",");
                        }
                        if (tokens.IsNext("out"))
                        {
                            outTokens.Add(tokens.Pop());
                        }
                        else
                        {
                            outTokens.Add(null);
                        }
                        args.Add(Parse(context, tokens, parent));
                    }
                    root = new FunctionInvocation(root.FirstToken, root, openParen, args, outTokens, parent);
                    break;

                case "{":     // e.g. new List<int>() { 1, 2, 3 }. This only follows a constructor.
                    FunctionInvocation            fi  = root as FunctionInvocation;
                    ConstructorInvocationFragment cif = fi == null ? null : (ConstructorInvocationFragment)fi.Root;
                    if (root is FunctionInvocation && ((FunctionInvocation)root).Root is ConstructorInvocationFragment)
                    {
                        tokens.Pop();     // {

                        ConstructorSuffixData format = DetermineConstructorSuffixDataFormat(tokens);

                        bool nextAllowed                = true;
                        List <Expression> values        = new List <Expression>();
                        List <Expression> kvpKeys       = new List <Expression>();
                        List <Token>      propertyNames = new List <Token>();
                        while (!tokens.PopIfPresent("}"))
                        {
                            if (!nextAllowed)
                            {
                                tokens.PopExpected("}");                   // intentionally throw
                            }
                            switch (format)
                            {
                            case ConstructorSuffixData.KVP_ENTRIES:
                                tokens.PopExpected("{");
                                kvpKeys.Add(Parse(context, tokens, parent));
                                tokens.PopExpected(",");
                                values.Add(Parse(context, tokens, parent));
                                tokens.PopExpected("}");
                                break;

                            case ConstructorSuffixData.PROPERTIES:
                                propertyNames.Add(tokens.PopWord());
                                tokens.PopExpected("=");
                                values.Add(Parse(context, tokens, parent));
                                break;

                            case ConstructorSuffixData.SEQUENTIAL_ITEMS:
                                values.Add(Parse(context, tokens, parent));
                                break;
                            }
                            nextAllowed = tokens.PopIfPresent(",");
                        }
                        cif.InitialDataValues = values.ToArray();
                        int t = cif.InitialDataValues.Length;
                        if (kvpKeys.Count == t)
                        {
                            cif.InitialDataKeys = kvpKeys.ToArray();
                        }
                        if (propertyNames.Count == t)
                        {
                            cif.InitialDataPropertyNames = propertyNames.ToArray();
                        }
                    }
                    else
                    {
                        throw new ParserException(tokens.Peek(), "Unexpected '{'");
                    }
                    break;

                default:
                    anythingInteresting = false;
                    break;
                }
                next = tokens.PeekValue();
            }

            if (next == "++" || next == "--")
            {
                Token incrementToken = tokens.Pop();
                root = new InlineIncrement(root.FirstToken, incrementToken, false, root, parent);
            }

            return(root);
        }
Esempio n. 6
0
        public override Expression ResolveTypes(ParserContext context, VariableScope varScope)
        {
            string name = this.Name.Value;

            if (name == "this" || name == "base")
            {
                if (name == "this")
                {
                    ClassLikeDefinition cd = this.Parent.ClassContainer;

                    return(new ThisKeyword(this.FirstToken, this.Parent)
                    {
                        ResolvedType = ResolvedType.FromClass(cd),
                    });
                }

                // TODO: base
                throw new System.NotImplementedException();
            }

            this.ResolvedType = varScope.GetVariableType(name);
            if (this.ResolvedType == null)
            {
                foreach (TopLevelEntity member in this.ClassContainer.GetMemberNonNull(name))
                {
                    if (member is PropertyDefinition || member is FieldDefinition || member is MethodDefinition)
                    {
                        VerifiedFieldReference vfr;
                        if (member.IsStatic)
                        {
                            ClassLikeDefinition  cd       = member.ClassContainer;
                            StaticClassReference classRef = new StaticClassReference(this.FirstToken, this.parent, member.ClassContainer);
                            vfr = new VerifiedFieldReference(this.FirstToken, this.parent, this.Name, classRef, ResolvedType.FromClass(cd));
                        }
                        else
                        {
                            ThisKeyword thisKeyword = new ThisKeyword(this.FirstToken, this.Parent);
                            thisKeyword.ResolvedType = ResolvedType.FromClass(this.Parent.ClassContainer);
                            vfr = new VerifiedFieldReference(this.FirstToken, this.parent, this.Name, thisKeyword, null);
                        }

                        if (member is PropertyDefinition)
                        {
                            vfr.Property     = (PropertyDefinition)member;
                            vfr.ResolvedType = vfr.Property.ResolvedType;
                        }
                        else if (member is FieldDefinition)
                        {
                            vfr.Field        = (FieldDefinition)member;
                            vfr.ResolvedType = vfr.Field.ResolvedType;
                        }
                        else if (member is MethodDefinition)
                        {
                            vfr.Method       = (MethodDefinition)member;
                            vfr.ResolvedType = vfr.Method.ResolvedReturnType;
                        }
                        else
                        {
                            throw new System.NotImplementedException();
                        }

                        return(vfr);
                    }
                    else
                    {
                        throw new System.NotImplementedException();
                    }
                }

                char c = this.Name.Value[0]; // lame optimization
                if (c >= 'A' && c <= 'Z')
                {
                    Expression newExpr = DotField.AttemptToResolveDotFieldChainIntoDirectReference(new Token[] { this.Name }, context, this);
                    if (newExpr != null)
                    {
                        return(newExpr);
                    }
                }

                throw new ParserException(this.FirstToken, "This variable is not declared.");
            }
            return(this);
        }
Esempio n. 7
0
        public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, FunctionCall funCall, bool outputUsed)
        {
            bool argCountIsNegativeOne       = false;
            FunctionDefinition ownerFunction = funCall.Owner as FunctionDefinition;

            if (ownerFunction != null &&
                ownerFunction.NameToken.Value == "_LIB_CORE_invoke" &&
                ownerFunction.FileScope.CompilationScope.Dependencies.Length == 0)
            {
                argCountIsNegativeOne = true;
            }

            Expression root = funCall.Root;

            if (root is FunctionReference)
            {
                FunctionReference  verifiedFunction = (FunctionReference)root;
                FunctionDefinition fd = verifiedFunction.FunctionDefinition;

                if (parser.InlinableLibraryFunctions.Contains(fd))
                {
                    CompileInlinedLibraryFunctionCall(bcc, parser, buffer, funCall, fd, outputUsed);
                }
                else
                {
                    bcc.CompileExpressionList(parser, buffer, funCall.Args, true);
                    if (fd.Owner is ClassDefinition)
                    {
                        ClassDefinition cd = (ClassDefinition)fd.Owner;
                        if (fd.Modifiers.HasStatic)
                        {
                            buffer.Add(
                                funCall.ParenToken,
                                OpCode.CALL_FUNCTION,
                                (int)FunctionInvocationType.STATIC_METHOD,
                                funCall.Args.Length,
                                fd.FunctionID,
                                outputUsed ? 1 : 0,
                                cd.ClassID);
                        }
                        else
                        {
                            buffer.Add(
                                funCall.ParenToken,
                                OpCode.CALL_FUNCTION,
                                (int)FunctionInvocationType.LOCAL_METHOD,
                                funCall.Args.Length,
                                fd.FunctionID,
                                outputUsed ? 1 : 0,
                                cd.ClassID,
                                verifiedFunction.FunctionDefinition.MemberID);
                        }
                    }
                    else
                    {
                        // vanilla function
                        buffer.Add(
                            funCall.ParenToken,
                            OpCode.CALL_FUNCTION,
                            (int)FunctionInvocationType.NORMAL_FUNCTION,
                            funCall.Args.Length,
                            fd.FunctionID,
                            outputUsed ? 1 : 0,
                            0);
                    }
                }
            }
            else if (root is DotField)
            {
                DotField   ds           = (DotField)root;
                Expression dotRoot      = ds.Root;
                int        globalNameId = parser.GetId(ds.FieldToken.Value);
                bcc.CompileExpression(parser, buffer, dotRoot, true);
                bcc.CompileExpressionList(parser, buffer, funCall.Args, true);
                int localeId = parser.GetLocaleId(ds.Owner.FileScope.CompilationScope.Locale);
                buffer.Add(
                    funCall.ParenToken,
                    OpCode.CALL_FUNCTION,
                    (int)FunctionInvocationType.FIELD_INVOCATION,
                    funCall.Args.Length,
                    0,
                    outputUsed ? 1 : 0,
                    globalNameId,
                    localeId);
            }
            else if (root is BaseMethodReference)
            {
                BaseMethodReference bmr = (BaseMethodReference)root;
                FunctionDefinition  fd  = bmr.ClassToWhichThisMethodRefers.GetMethod(bmr.FieldToken.Value, true);
                if (fd == null)
                {
                    throw new ParserException(bmr.DotToken, "This method does not exist on any base class.");
                }

                bcc.CompileExpressionList(parser, buffer, funCall.Args, true);
                buffer.Add(
                    funCall.ParenToken,
                    OpCode.CALL_FUNCTION,
                    (int)FunctionInvocationType.LOCAL_METHOD,
                    funCall.Args.Length,
                    fd.FunctionID,
                    outputUsed ? 1 : 0,
                    bmr.ClassToWhichThisMethodRefers.ClassID,
                    -1);
            }
            else
            {
                bcc.CompileExpression(parser, buffer, root, true);
                bcc.CompileExpressionList(parser, buffer, funCall.Args, true);
                buffer.Add(
                    funCall.ParenToken,
                    OpCode.CALL_FUNCTION,
                    (int)FunctionInvocationType.POINTER_PROVIDED,
                    argCountIsNegativeOne ? -1 : funCall.Args.Length,
                    0,
                    outputUsed ? 1 : 0,
                    0);
            }
        }
Esempio n. 8
0
        public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, Assignment assignment)
        {
            Expression target = assignment.Target;
            Expression value  = assignment.Value;

            ResolvedType targetAssignmentType = target.ResolvedType;

            if (targetAssignmentType == null)
            {
                throw new Exception();                               // should be ANY if no type is set.
            }
            if (value.ResolvedType == ResolvedType.ANY &&
                targetAssignmentType != ResolvedType.ANY)
            {
                value = new Cast(value.FirstToken, targetAssignmentType, value, value.Owner, false);
            }

            if (assignment.Op == Ops.EQUALS)
            {
                if (assignment.Target is Variable)
                {
                    Variable varTarget = (Variable)assignment.Target;
                    bcc.CompileExpression(parser, buffer, value, true);
                    VariableId varId = varTarget.VarId;
                    if (varId.UsedByClosure)
                    {
                        buffer.Add(assignment.OpToken, OpCode.ASSIGN_CLOSURE, varId.ClosureID);
                    }
                    else
                    {
                        buffer.Add(assignment.OpToken, OpCode.ASSIGN_LOCAL, varId.ID);
                    }
                }
                else if (assignment.Target is BracketIndex)
                {
                    BracketIndex bi = (BracketIndex)assignment.Target;
                    bcc.CompileExpression(parser, buffer, bi.Root, true);
                    bcc.CompileExpression(parser, buffer, bi.Index, true);
                    bcc.CompileExpression(parser, buffer, value, true);
                    buffer.Add(assignment.OpToken, OpCode.ASSIGN_INDEX, 0);
                }
                else if (assignment.Target is DotField)
                {
                    DotField dotStep = (DotField)assignment.Target;
                    if (dotStep.Root is ThisKeyword)
                    {
                        bcc.CompileExpression(parser, buffer, value, true);
                        buffer.Add(assignment.OpToken, OpCode.ASSIGN_THIS_FIELD, parser.GetId(dotStep.FieldToken.Value));
                    }
                    else
                    {
                        bcc.CompileExpression(parser, buffer, dotStep.Root, true);
                        bcc.CompileExpression(parser, buffer, value, true);
                        int nameId             = parser.GetId(dotStep.FieldToken.Value);
                        int localeScopedNameId = nameId * parser.GetLocaleCount() + parser.GetLocaleId(dotStep.Owner.FileScope.CompilationScope.Locale);
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_FIELD,
                            nameId,
                            0,
                            localeScopedNameId,
                            assignment.ClassOwner == null ? -1 : assignment.ClassOwner.ClassID,
                            assignment.CompilationScope.ScopeNumId,
                            -1, 0);
                    }
                }
                else if (assignment.Target is FieldReference)
                {
                    bcc.CompileExpression(parser, buffer, value, true);
                    FieldReference fieldReference = (FieldReference)assignment.Target;
                    if (fieldReference.Field.Modifiers.HasStatic)
                    {
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_STATIC_FIELD,
                            ((ClassDefinition)fieldReference.Field.Owner).ClassID,
                            fieldReference.Field.StaticMemberID);
                    }
                    else
                    {
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_THIS_FIELD,
                            fieldReference.Field.MemberID);
                    }
                }
                else
                {
                    throw new Exception("This shouldn't happen.");
                }
            }
            else
            {
                Ops op = assignment.Op;
                if (assignment.Target is Variable)
                {
                    Variable   varTarget = (Variable)assignment.Target;
                    VariableId varId     = varTarget.VarId;
                    bool       isClosure = varId.UsedByClosure;
                    int        scopeId   = isClosure ? varId.ClosureID : varId.ID;

                    buffer.Add(varTarget.FirstToken, isClosure ? OpCode.DEREF_CLOSURE : OpCode.LOCAL, scopeId);
                    bcc.CompileExpression(parser, buffer, value, true);
                    buffer.Add(assignment.OpToken, OpCode.BINARY_OP, (int)op);
                    buffer.Add(assignment.Target.FirstToken, isClosure ? OpCode.ASSIGN_CLOSURE : OpCode.ASSIGN_LOCAL, scopeId);
                }
                else if (assignment.Target is DotField)
                {
                    DotField dotExpr            = (DotField)assignment.Target;
                    int      fieldId            = parser.GetId(dotExpr.FieldToken.Value);
                    int      localeScopedStepId = parser.GetLocaleCount() * fieldId + parser.GetLocaleId(dotExpr.Owner.FileScope.CompilationScope.Locale);
                    bcc.CompileExpression(parser, buffer, dotExpr.Root, true);
                    if (!(dotExpr.Root is ThisKeyword))
                    {
                        buffer.Add(null, OpCode.DUPLICATE_STACK_TOP, 1);
                    }
                    buffer.Add(
                        dotExpr.DotToken,
                        OpCode.DEREF_DOT,
                        fieldId,
                        localeScopedStepId,
                        assignment.ClassOwner == null ? -1 : assignment.ClassOwner.ClassID,
                        assignment.CompilationScope.ScopeNumId,
                        -1, 0);
                    bcc.CompileExpression(parser, buffer, value, true);
                    buffer.Add(assignment.OpToken, OpCode.BINARY_OP, (int)op);
                    if (dotExpr.Root is ThisKeyword)
                    {
                        buffer.Add(assignment.OpToken, OpCode.ASSIGN_THIS_FIELD, fieldId);
                    }
                    else
                    {
                        int localeScopedNameId = fieldId * parser.GetLocaleCount() + parser.GetLocaleId(dotExpr.Owner.FileScope.CompilationScope.Locale);
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_FIELD,
                            fieldId,
                            0,
                            localeScopedNameId,
                            assignment.ClassOwner == null ? -1 : assignment.ClassOwner.ClassID,
                            assignment.CompilationScope.ScopeNumId,
                            -1, 0);
                    }
                }
                else if (assignment.Target is BracketIndex)
                {
                    BracketIndex indexExpr = (BracketIndex)assignment.Target;
                    bcc.CompileExpression(parser, buffer, indexExpr.Root, true);
                    bcc.CompileExpression(parser, buffer, indexExpr.Index, true);
                    buffer.Add(null, OpCode.DUPLICATE_STACK_TOP, 2);
                    buffer.Add(indexExpr.BracketToken, OpCode.INDEX);
                    bcc.CompileExpression(parser, buffer, value, true);
                    buffer.Add(assignment.OpToken, OpCode.BINARY_OP, (int)op);
                    buffer.Add(assignment.OpToken, OpCode.ASSIGN_INDEX, 0);
                }
                else if (assignment.Target is FieldReference)
                {
                    FieldReference fieldRef = (FieldReference)assignment.Target;
                    FieldReferenceEncoder.Compile(parser, buffer, fieldRef, true);
                    bcc.CompileExpression(parser, buffer, value, true);
                    buffer.Add(assignment.OpToken, OpCode.BINARY_OP, (int)op);

                    if (fieldRef.Field.Modifiers.HasStatic)
                    {
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_STATIC_FIELD,
                            ((ClassDefinition)fieldRef.Field.Owner).ClassID,
                            fieldRef.Field.StaticMemberID);
                    }
                    else
                    {
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_THIS_FIELD,
                            fieldRef.Field.MemberID);
                    }
                }
                else
                {
                    throw new ParserException(assignment.OpToken, "Assignment is not allowed on this sort of expression.");
                }
            }
        }
Esempio n. 9
0
        public void TranslateExpression(StringBuilder 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 "NativeFunctionInvocation": this.TranslateNativeFunctionInvocation(sb, (NativeFunctionInvocation)expression); break;

            case "OpChain": this.TranslateOpChain(sb, (OpChain)expression); break;

            case "LibraryNativeFunctionInvocation": this.TranslateLibraryNativeFunctionInvocation(sb, (LibraryNativeFunctionInvocation)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;
                bool specifyInterpreterScope      = false;
                if (funcInvocation.FirstToken.FileName.StartsWith("LIB:") &&
                    funcInvocation.Root is FunctionReference)
                {
                    FunctionDefinition funcDef = ((FunctionReference)funcInvocation.Root).Function;
                    if (!funcDef.NameToken.FileName.StartsWith("LIB:"))
                    {
                        specifyInterpreterScope = true;
                    }
                }

                if (specifyInterpreterScope)
                {
                    this.TranslateFunctionInvocationInterpreterScoped(sb, (FunctionReference)funcInvocation.Root, funcInvocation.Args);
                }
                else
                {
                    this.TranslateFunctionInvocationLocallyScoped(sb, (FunctionReference)funcInvocation.Root, funcInvocation.Args);
                }
                break;

            case "Variable":
                Variable v         = (Variable)expression;
                string   name      = v.Name;
                char     firstChar = name[0];
                if (firstChar >= 'A' && firstChar <= 'Z' && name.Contains('_') && name.ToUpper() == name)
                {
                    this.TranslateGlobalVariable(sb, v);
                }
                else
                {
                    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;

                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;
                if (structDef == null)
                {
                    throw new InvalidOperationException();                        // should have been thrown by the compiler
                }
                string fieldName  = df.FieldName.Value;
                int    fieldIndex = structDef.ArgIndexByName[fieldName];
                this.TranslateStructFieldDereference(sb, df.Root, structDef, fieldName, fieldIndex);
                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 "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);
            }
        }
Esempio n. 10
0
        private Expression ParseEntity(TokenStream tokens, Node owner)
        {
            Expression root;
            Token      firstToken = tokens.Peek();
            AType      castPrefix = firstToken.Value == "(" ? this.MaybeParseCastPrefix(tokens) : null;

            if (castPrefix != null)
            {
                root = this.ParseEntity(tokens, owner);
                return(new Cast(firstToken, castPrefix, root, owner, true));
            }

            Token maybeOpenParen = tokens.Peek();

            if (tokens.PopIfPresent("("))
            {
                if (tokens.PopIfPresent(")"))
                {
                    root = this.ParseLambda(tokens, firstToken, new AType[0], new Token[0], owner);
                }
                else
                {
                    if (this.parser.CurrentScope.IsStaticallyTyped)
                    {
                        TokenStream.StreamState state = tokens.RecordState();
                        AType lambdaArgType           = this.parser.TypeParser.TryParse(tokens);
                        Token lambdaArg = null;
                        if (lambdaArgType != null)
                        {
                            lambdaArg = tokens.PopIfWord();
                        }

                        if (lambdaArg != null)
                        {
                            List <AType> lambdaArgTypes = new List <AType>()
                            {
                                lambdaArgType
                            };
                            List <Token> lambdaArgs = new List <Token>()
                            {
                                lambdaArg
                            };
                            while (tokens.PopIfPresent(","))
                            {
                                lambdaArgTypes.Add(this.parser.TypeParser.Parse(tokens));
                                lambdaArgs.Add(tokens.PopWord());
                            }
                            tokens.PopExpected(")");
                            return(this.ParseLambda(tokens, maybeOpenParen, lambdaArgTypes, lambdaArgs, owner));
                        }
                        else
                        {
                            tokens.RestoreState(state);
                        }
                    }

                    root = this.Parse(tokens, owner);
                    if (root is Variable)
                    {
                        if (tokens.PopIfPresent(")"))
                        {
                            if (tokens.IsNext("=>"))
                            {
                                root = this.ParseLambda(tokens, firstToken, new AType[] { AType.Any(root.FirstToken) }, new Token[] { root.FirstToken }, owner);
                            }
                        }
                        else if (tokens.IsNext(","))
                        {
                            List <Token> lambdaArgs = new List <Token>()
                            {
                                root.FirstToken
                            };
                            List <AType> lambdaArgTypes = new List <AType>()
                            {
                                AType.Any(root.FirstToken)
                            };
                            Token comma = tokens.Peek();
                            while (tokens.PopIfPresent(","))
                            {
                                Token nextArg = tokens.Pop();
                                if (nextArg.Type != TokenType.WORD)
                                {
                                    throw new ParserException(comma, "Unexpected comma.");
                                }
                                lambdaArgTypes.Add(AType.Any(nextArg));
                                lambdaArgs.Add(nextArg);
                                comma = tokens.Peek();
                            }
                            tokens.PopExpected(")");

                            root = this.ParseLambda(tokens, firstToken, lambdaArgTypes, lambdaArgs, owner);
                        }
                        else
                        {
                            // This will purposely cause an unexpected token error
                            // since it's none of the above conditions.
                            tokens.PopExpected(")");
                        }
                    }
                    else
                    {
                        tokens.PopExpected(")");
                    }
                }
            }
            else
            {
                root = ParseEntityWithoutSuffixChain(tokens, owner);
            }
            bool anySuffixes    = true;
            bool isPreviousADot = false;

            while (anySuffixes)
            {
                if (tokens.IsNext("."))
                {
                    isPreviousADot = true;
                    Token dotToken   = tokens.Pop();
                    Token fieldToken = tokens.Pop();
                    // HACK alert: "class" is a valid field on a class.
                    // ParserVerifyIdentifier is invoked downstream for non-resolved fields.
                    if (fieldToken.Value != this.parser.Keywords.CLASS)
                    {
                        this.parser.VerifyIdentifier(fieldToken);
                    }
                    root = new DotField(root, dotToken, fieldToken, owner);
                }
                else if (tokens.IsNext("["))
                {
                    Token             openBracket     = tokens.Pop();
                    List <Expression> sliceComponents = new List <Expression>();
                    if (tokens.IsNext(":"))
                    {
                        sliceComponents.Add(null);
                    }
                    else
                    {
                        sliceComponents.Add(Parse(tokens, owner));
                    }

                    for (int i = 0; i < 2; ++i)
                    {
                        if (tokens.PopIfPresent(":"))
                        {
                            if (tokens.IsNext(":") || tokens.IsNext("]"))
                            {
                                sliceComponents.Add(null);
                            }
                            else
                            {
                                sliceComponents.Add(Parse(tokens, owner));
                            }
                        }
                    }

                    tokens.PopExpected("]");

                    if (sliceComponents.Count == 1)
                    {
                        Expression index = sliceComponents[0];
                        root = new BracketIndex(root, openBracket, index, owner);
                    }
                    else
                    {
                        root = new ListSlice(root, sliceComponents, openBracket, owner);
                    }
                }
                else if (tokens.IsNext("("))
                {
                    Token             openParen = tokens.Pop();
                    List <Expression> args      = new List <Expression>();
                    while (!tokens.PopIfPresent(")"))
                    {
                        if (args.Count > 0)
                        {
                            tokens.PopExpected(",");
                        }

                        args.Add(Parse(tokens, owner));
                    }
                    root = new FunctionCall(root, openParen, args, owner);
                }
                else if (tokens.IsNext(this.parser.Keywords.IS))
                {
                    Token  isToken    = tokens.Pop();
                    Token  classToken = tokens.Pop();
                    string className  = this.parser.PopClassNameWithFirstTokenAlreadyPopped(tokens, classToken);
                    root = new IsComparison(root, isToken, classToken, className, owner);
                }
                else if (isPreviousADot && this.parser.IsCSharpCompat && tokens.IsNext("<"))
                {
                    TokenStream.StreamState s = tokens.RecordState();
                    Token openBracket         = tokens.Pop();
                    AType funcType            = this.parser.TypeParser.TryParse(tokens);

                    List <AType> types = new List <AType>()
                    {
                        funcType
                    };
                    if (funcType != null)
                    {
                        while (tokens.PopIfPresent(","))
                        {
                            types.Add(this.parser.TypeParser.Parse(tokens));
                        }
                    }

                    if (funcType == null)
                    {
                        anySuffixes = false;
                        tokens.RestoreState(s);
                    }
                    else if (!tokens.PopIfPresent(">") || !tokens.IsNext("("))
                    {
                        anySuffixes = false;
                        tokens.RestoreState(s);
                    }
                    else
                    {
                        // TODO(acrylic-conversion): do something with this types list.
                    }
                }
                else
                {
                    anySuffixes = false;
                }
            }
            return(root);
        }
Esempio n. 11
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);
            }
        }
Esempio n. 12
0
        public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, Increment increment, bool outputUsed)
        {
            if (!outputUsed)
            {
                throw new Exception("This should have been optimized into a += or -=");
            }

            if (increment.Root is Variable)
            {
                // OpCode re-use be damned. This should be not one, but two top-level op codes.
                // INCREMENT_INLINE and INCREMENT_POP (depending on whether outputUsed is true)
                // In fact, the code here in its current form is actually WRONG because someString++ will have
                // a '1' appended to it when it really should be an error if the variable is not an integer.
                // Same for the others below. Ideally the DUPLICATE_STACK_TOP op should be removed.
                Variable   variable     = (Variable)increment.Root;
                VariableId varId        = variable.VarId;
                bool       isClosureVar = varId.UsedByClosure;
                int        scopeId      = isClosureVar ? varId.ClosureID : varId.ID;
                bcc.CompileExpression(parser, buffer, increment.Root, true);
                if (increment.IsPrefix)
                {
                    buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
                    buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 1);
                    buffer.Add(variable.FirstToken, isClosureVar ? OpCode.ASSIGN_CLOSURE : OpCode.ASSIGN_LOCAL, scopeId);
                }
                else
                {
                    buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 1);
                    buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
                    buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(variable.FirstToken, isClosureVar ? OpCode.ASSIGN_CLOSURE : OpCode.ASSIGN_LOCAL, scopeId);
                }
            }
            else if (increment.Root is BracketIndex)
            {
                BracketIndex bracketIndex = (BracketIndex)increment.Root;
                bcc.CompileExpression(parser, buffer, bracketIndex.Root, true);
                bcc.CompileExpression(parser, buffer, bracketIndex.Index, true);
                buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 2);
                buffer.Add(bracketIndex.BracketToken, OpCode.INDEX);
                if (increment.IsPrefix)
                {
                    buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
                    buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(increment.IncrementToken, OpCode.ASSIGN_INDEX, 1);
                }
                else
                {
                    buffer.Add(increment.IncrementToken, OpCode.STACK_INSERTION_FOR_INCREMENT);
                    buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
                    buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(increment.IncrementToken, OpCode.ASSIGN_INDEX, 0);
                }
            }
            else if (increment.Root is DotField)
            {
                DotField dotStep = (DotField)increment.Root;
                bcc.CompileExpression(parser, buffer, dotStep.Root, true);
                buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 1);
                int nameId             = parser.GetId(dotStep.FieldToken.Value);
                int localeScopedNameId = nameId * parser.GetLocaleCount() + parser.GetLocaleId(dotStep.Owner.FileScope.CompilationScope.Locale);
                int originClassId      = increment.ClassOwner == null ? -1 : increment.ClassOwner.ClassID;
                int originAssemblyId   = increment.CompilationScope.ScopeNumId;
                buffer.Add(
                    dotStep.DotToken,
                    OpCode.DEREF_DOT,
                    nameId,
                    localeScopedNameId,
                    originClassId,
                    increment.CompilationScope.ScopeNumId,
                    -1, 0);
                if (increment.IsPrefix)
                {
                    buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
                    buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(increment.IncrementToken, OpCode.ASSIGN_FIELD, nameId, 1, localeScopedNameId, originClassId, originAssemblyId, -1, 0);
                }
                else
                {
                    buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 2);
                    buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
                    buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(increment.IncrementToken, OpCode.ASSIGN_FIELD, nameId, 0, localeScopedNameId, originClassId, originAssemblyId, -1, 0);
                    buffer.Add(increment.IncrementToken, OpCode.STACK_SWAP_POP);
                }
            }
            else if (increment.Root is FieldReference)
            {
                FieldReference  fr       = (FieldReference)increment.Root;
                bool            isStatic = fr.Field.Modifiers.HasStatic;
                ClassDefinition cd       = (ClassDefinition)fr.Field.Owner;
                int             memberId = isStatic ? fr.Field.StaticMemberID : fr.Field.MemberID;

                bcc.CompileExpression(parser, buffer, fr, true);
                if (increment.IsPrefix)
                {
                    buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
                    buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 1);
                }
                else
                {
                    buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 1);
                    buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
                    buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)Ops.ADDITION : (int)Ops.SUBTRACTION);
                }
                Token token = increment.IsPrefix ? increment.FirstToken : fr.FirstToken;
                if (isStatic)
                {
                    buffer.Add(token, OpCode.ASSIGN_STATIC_FIELD, ((ClassDefinition)fr.Field.Owner).ClassID, memberId);
                }
                else
                {
                    buffer.Add(token, OpCode.ASSIGN_THIS_FIELD, memberId);
                }
            }
            else
            {
                throw new ParserException(increment.IncrementToken, "Cannot apply " + (increment.IsIncrement ? "++" : "--") + " to this sort of expression.");
            }
        }