Beispiel #1
0
        internal void CompileExpression(ParserContext parser, ByteBuffer buffer, Expression expr, bool outputUsed)
        {
            if (expr is FunctionCall)
            {
                FunctionCallEncoder.Compile(this, parser, buffer, (FunctionCall)expr, outputUsed);
            }
            else if (expr is IntegerConstant)
            {
                ConstantEncoder.CompileInteger(parser, buffer, (IntegerConstant)expr, outputUsed);
            }
            else if (expr is Variable)
            {
                VariableEncoder.Compile(parser, buffer, (Variable)expr, outputUsed);
            }
            else if (expr is BooleanConstant)
            {
                ConstantEncoder.CompileBoolean(parser, buffer, (BooleanConstant)expr, outputUsed);
            }
            else if (expr is DotField)
            {
                DotFieldEncoder.Compile(this, parser, buffer, (DotField)expr, outputUsed);
            }
            else if (expr is BracketIndex)
            {
                BracketIndexEncoder.Compile(this, parser, buffer, (BracketIndex)expr, outputUsed);
            }
            else if (expr is OpChain)
            {
                OpChainEncoder.Compile(this, parser, buffer, (OpChain)expr, outputUsed);
            }
            else if (expr is StringConstant)
            {
                ConstantEncoder.CompileString(parser, buffer, (StringConstant)expr, outputUsed);
            }
            else if (expr is NegativeSign)
            {
                NegativeSignEncoder.Compile(this, parser, buffer, (NegativeSign)expr, outputUsed);
            }
            else if (expr is ListDefinition)
            {
                ListDefinitionEncoder.Compile(this, parser, buffer, (ListDefinition)expr, outputUsed);
            }
            else if (expr is Increment)
            {
                IncrementEncoder.Compile(this, parser, buffer, (Increment)expr, outputUsed);
            }
            else if (expr is FloatConstant)
            {
                ConstantEncoder.CompileFloat(parser, buffer, (FloatConstant)expr, outputUsed);
            }
            else if (expr is NullConstant)
            {
                ConstantEncoder.CompileNull(parser, buffer, (NullConstant)expr, outputUsed);
            }
            else if (expr is ThisKeyword)
            {
                ThisEncoder.Compile(parser, buffer, (ThisKeyword)expr, outputUsed);
            }
            else if (expr is Instantiate)
            {
                InstantiateEncoder.Compile(this, parser, buffer, (Instantiate)expr, outputUsed);
            }
            else if (expr is DictionaryDefinition)
            {
                DictionaryDefinitionEncoder.Compile(this, parser, buffer, (DictionaryDefinition)expr, outputUsed);
            }
            else if (expr is BooleanCombination)
            {
                BooleanCombinationEncoder.Compile(this, parser, buffer, (BooleanCombination)expr, outputUsed);
            }
            else if (expr is BooleanNot)
            {
                BooleanNotEncoder.Compile(this, parser, buffer, (BooleanNot)expr, outputUsed);
            }
            else if (expr is Cast)
            {
                CastEncoder.Compile(this, parser, buffer, (Cast)expr, outputUsed);
            }
            else if (expr is Ternary)
            {
                TernaryEncoder.Compile(this, parser, buffer, (Ternary)expr, outputUsed);
            }
            else if (expr is ListSlice)
            {
                ListSliceEncoder.Compile(this, parser, buffer, (ListSlice)expr, outputUsed);
            }
            else if (expr is NullCoalescer)
            {
                NullCoalescerEncoder.Compile(this, parser, buffer, (NullCoalescer)expr, outputUsed);
            }
            else if (expr is BaseMethodReference)
            {
                BaseMethodReferenceEncoder.Compile(parser, buffer, (BaseMethodReference)expr, outputUsed);
            }
            else if (expr is FunctionReference)
            {
                FunctionReferenceEncoder.Compile(parser, buffer, (FunctionReference)expr, outputUsed);
            }
            else if (expr is FieldReference)
            {
                FieldReferenceEncoder.Compile(parser, buffer, (FieldReference)expr, outputUsed);
            }
            else if (expr is CoreFunctionInvocation)
            {
                CoreFunctionInvocationEncoder.Compile(this, parser, buffer, (CoreFunctionInvocation)expr, null, null, outputUsed);
            }
            else if (expr is IsComparison)
            {
                IsComparisonEncoder.Compile(this, parser, buffer, (IsComparison)expr, outputUsed);
            }
            else if (expr is ClassReferenceLiteral)
            {
                ClassReferenceEncoder.Compile(parser, buffer, (ClassReferenceLiteral)expr, outputUsed);
            }
            else if (expr is Lambda)
            {
                LambdaEncoder.Compile(this, parser, buffer, (Lambda)expr, outputUsed);
            }
            else if (expr is PrimitiveMethodReference)
            {
                DotFieldEncoder.Compile(this, parser, buffer, (PrimitiveMethodReference)expr, outputUsed);
            }

            // The following parse tree items must be removed before reaching the byte code encoder.
            else if (expr is BaseKeyword)
            {
                this.CompileBaseKeyword(parser, buffer, (BaseKeyword)expr, outputUsed);
            }
            else if (expr is CompileTimeDictionary)
            {
                this.CompileCompileTimeDictionary((CompileTimeDictionary)expr);
            }


            else
            {
                throw new NotImplementedException();
            }
        }
Beispiel #2
0
        private void CompileClass(ParserContext parser, ByteBuffer buffer, ClassDefinition classDefinition)
        {
            bool hasStaticFieldsWithStartingValues = classDefinition.Fields
                                                     .Where(fd =>
                                                            fd.Modifiers.HasStatic &&
                                                            fd.DefaultValue != null &&
                                                            !(fd.DefaultValue is NullConstant))
                                                     .Count() > 0;

            if (hasStaticFieldsWithStartingValues)
            {
                if (classDefinition.StaticConstructor == null)
                {
                    classDefinition.StaticConstructor = new ConstructorDefinition(null, ModifierCollection.CreateStaticModifier(classDefinition.FirstToken), new AnnotationCollection(parser), classDefinition);
                    classDefinition.StaticConstructor.Resolve(parser);
                }

                List <Executable> staticFieldInitializers = new List <Executable>();
                foreach (FieldDefinition fd in classDefinition.Fields)
                {
                    if (fd.Modifiers.HasStatic && fd.DefaultValue != null && !(fd.DefaultValue is NullConstant))
                    {
                        FieldReference fieldRef = new FieldReference(fd.FirstToken, fd, fd);
                        fieldRef.ResolvedType = fd.ResolvedFieldType;
                        Executable assignment = new Assignment(
                            fieldRef,
                            null,
                            fd.NameToken,
                            Ops.EQUALS,
                            fd.DefaultValue,
                            fd);
                        staticFieldInitializers.Add(assignment);
                    }
                }

                staticFieldInitializers.AddRange(classDefinition.StaticConstructor.Code);
                classDefinition.StaticConstructor.Code = staticFieldInitializers.ToArray();
            }

            if (classDefinition.StaticConstructor != null)
            {
                // All static field initializers are added here.
                ConstructorDefinitionEncoder.Compile(this, parser, buffer, classDefinition.StaticConstructor, null);
            }

            foreach (FunctionDefinition fd in classDefinition.Methods)
            {
                int pc = buffer.Size;
                fd.FinalizedPC = pc;
                FunctionDefinitionEncoder.Compile(this, parser, buffer, fd, true);
            }

            int classId             = classDefinition.ClassID;
            int baseClassId         = classDefinition.BaseClass != null ? classDefinition.BaseClass.ClassID : -1;
            int nameId              = parser.GetId(classDefinition.NameToken.Value);
            int constructorId       = classDefinition.Constructor.FunctionID;
            int staticConstructorId = classDefinition.StaticConstructor != null ? classDefinition.StaticConstructor.FunctionID : -1;

            int staticFieldCount = classDefinition.Fields.Where <FieldDefinition>(fd => fd.Modifiers.HasStatic).Count();

            FieldDefinition[]      regularFields           = classDefinition.Fields.Where <FieldDefinition>(fd => !fd.Modifiers.HasStatic).ToArray();
            FunctionDefinition[]   regularMethods          = classDefinition.Methods.Where <FunctionDefinition>(fd => !fd.Modifiers.HasStatic).ToArray();
            List <int>             members                 = new List <int>();
            List <FieldDefinition> fieldsWithComplexValues = new List <FieldDefinition>();

            foreach (FieldDefinition fd in regularFields)
            {
                int memberId    = fd.MemberID;
                int fieldNameId = parser.GetId(fd.NameToken.Value);
                int initInstruction;
                int literalId = 0;

                // TODO: get rid of init instruction since everything is just 0 now.
                initInstruction = 0;
                literalId       = parser.GetLiteralId(fd.DefaultValue);
                if (literalId == -1)
                {
                    literalId = parser.GetNullConstant();
                    fieldsWithComplexValues.Add(fd);
                }

                members.AddRange(new int[] {
                    0, // flag for field
                    memberId,
                    fieldNameId,
                    initInstruction,
                    literalId,
                    EncodeAccessModifier(fd.Modifiers)
                });
            }

            foreach (FunctionDefinition fd in regularMethods)
            {
                int memberId     = fd.MemberID;
                int methodNameId = parser.GetId(fd.NameToken.Value);
                int functionId   = fd.FunctionID;

                members.AddRange(new int[] {
                    1, // flag for method
                    memberId,
                    methodNameId,
                    functionId,
                    0, // ignored value.
                    EncodeAccessModifier(fd.Modifiers),
                });
            }

            ByteBuffer initializer = new ByteBuffer();

            if (fieldsWithComplexValues.Count > 0)
            {
                foreach (FieldDefinition complexField in fieldsWithComplexValues)
                {
                    this.CompileExpression(parser, initializer, complexField.DefaultValue, true);
                    initializer.Add(complexField.FirstToken, OpCode.ASSIGN_THIS_FIELD, complexField.MemberID);
                }
            }

            ConstructorDefinitionEncoder.Compile(this, parser, buffer, classDefinition.Constructor, initializer);

            List <int> args = new List <int>()
            {
                classId,
                baseClassId,
                nameId,
                constructorId,
                staticConstructorId,
                staticFieldCount,
                classDefinition.CompilationScope.ScopeNumId,
            };

            args.AddRange(members);

            string fullyQualifiedName = classDefinition.GetFullyQualifiedLocalizedName(parser.RootScope.Locale);

            buffer.Add(classDefinition.FirstToken, OpCode.CLASS_DEFINITION, fullyQualifiedName, args.ToArray());
            foreach (FieldDefinition fd in classDefinition.Fields)
            {
                if (fd.ResolvedFieldType != parser.TypeContext.ANY && !fd.Modifiers.HasStatic)
                {
                    List <int> typeArgs = new List <int>();
                    typeArgs.Add(classDefinition.ClassID);
                    typeArgs.Add(fd.MemberID);
                    // TODO: change the last boolean to an enum to include behavior for not including FLOAT/INT conversion info
                    CastEncoder.EncodeTypeInfoToIntBuffer(typeArgs, fd.ResolvedFieldType, false);
                    buffer.Add(null, OpCode.FIELD_TYPE_INFO, typeArgs.ToArray());
                }
            }
        }