public Item Compile(ByteCodeGenerator generator)
        {
            Chain thenExit = null;

            var item = new ConditionCompiler(node.Condition).Compile(generator);
            var elseChain = item.JumpFalse();

            Item x = null;
            if (!item.IsFalse())
            {
                generator.ResolveChain(item.TrueJumps);

                x = new ExpressionCompiler(node.ThenExpression).Compile(generator).Load();

                thenExit = generator.Branch(OpCodeValue.@goto);
            }
            if (elseChain != null)
            {
                generator.ResolveChain(elseChain);

                x = new ExpressionCompiler(node.ElseExpression).Compile(generator).Load();
            }
            generator.ResolveChain(thenExit);

            //var type = tb.Type.FindCommonType(fb.Type);
            var type = x.Type;

            return new StackItem(generator, type);
        }
        public Item Compile(ByteCodeGenerator generator)
        {
            var type = node.GetType(generator);

            var lhs = new TranslationCompiler(node.LeftChild, type).Compile(generator);
            var rhs = new TranslationCompiler(node.RightChild, type).Compile(generator);

            if (!type.Primitive)
            {
                throw new InvalidOperationException();
            }

            lhs.Load();
            rhs.Load();

            if (node is MultiplicativeNode.MultiplicativeMultiplyNode)
            {
                CompileMultiplication(generator, type);
            }
            else if (node is MultiplicativeNode.MultiplicativeDivideNode)
            {
                CompileDivide(generator, type);
            }
            else if (node is MultiplicativeNode.MultiplicativeModNode)
            {
                CompileMod(generator, type);
            }

            return new StackItem(generator, type);
        }
        private void CompileReturn(ByteCodeGenerator generator, Type type)
        {
            var typeCode = TypeCodeHelper.Truncate(PrimativeTypes.TypeCode(type));

            switch (typeCode)
            {
                case ItemTypeCode.Int:
                    generator.Emit(OpCodeValue.ireturn);
                    break;
                case ItemTypeCode.Long:
                    generator.Emit(OpCodeValue.lreturn);
                    break;
                case ItemTypeCode.Float:
                    generator.Emit(OpCodeValue.freturn);
                    break;
                case ItemTypeCode.Double:
                    generator.Emit(OpCodeValue.dreturn);
                    break;
                case ItemTypeCode.Object:
                    generator.Emit(OpCodeValue.areturn);
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
        public void Compile(ByteCodeGenerator generator)
        {
            MethodTreeNode first = tree.FirstOrDefault();
            if (first == null)
            {
                CompileSuperCall(generator);
            }
            else
            {
                if (first is PrimaryNode.TermConstructorCallExpression)
                {
                    var call = first as PrimaryNode.TermConstructorCallExpression;

                    CompileSuperCall(generator, call);

                    tree.RemoveAt(0);
                }
                else
                {
                    CompileSuperCall(generator);
                }
            }

            new BlockCompiler(tree).Compile(generator);

            generator.Emit(OpCodeValue.@return);
        }
        private void CompileBody(CompileManager manager)
        {
            attributes = new List<CompileAttribute>();
            generator = new ByteCodeGenerator(manager, (Method)constructor);

            foreach (Method.Parameter parameter in constructor.Parameters)
            {
                generator.DefineVariable(parameter.Name, parameter.Type);
            }

            new ConstructorBlockCompiler(constructor.Body).Compile(generator);

            attributes.Add(new CompileAttributeCode
            {
                NameIndex = manager.AddConstantUtf8(new CompileAttributeCode().Name),
                Code = generator.GetBytes(),
                Attributes = new List<CompileAttribute>(),
                ExceptionTable = new List<CompileAttributeCode.ExceptionTableEntry>(),
                MaxLocals = generator.MaxVariables,
                MaxStack = generator.MaxStack
            });

            var stackMapTable = generator.StackMapTable;
            if (stackMapTable != null)
            {
                stackMapTable.NameIndex = manager.AddConstantUtf8(stackMapTable.Name);

                attributes.Add(stackMapTable);
            }
        }
Beispiel #6
0
        public void Compile(ByteCodeGenerator generator)
        {
            var item = new ConditionCompiler(node.Condition).Compile(generator);
            var elseChain = item.JumpFalse();

            Chain thenExit = null;
            if (!item.IsFalse())
            {
                generator.ResolveChain(item.TrueJumps);

                generator.PushScope();

                new StatementCompiler(node.TrueBranch).Compile(generator);
                thenExit = generator.Branch(OpCodeValue.@goto);

                generator.PopScope();
            }
            if (elseChain != null)
            {
                generator.ResolveChain(elseChain);

                if (node.FalseBranch != null)
                {
                    generator.PushScope();
                    new StatementCompiler(node.FalseBranch).Compile(generator);
                    generator.PopScope();
                }
            }

            generator.ResolveChain(thenExit);
        }
        public Item Compile(ByteCodeGenerator generator)
        {
            //TODO
            var item = new ExpressionCompiler(node.Child.Child).Compile(generator);

            if (node is UnaryNode.PlusNode)
            {
                return item.Load();
            }
            if (node is UnaryNode.MinusNode)
            {
                throw new NotImplementedException();
            }

            if (node is UnaryNode.PreIncNode)
            {
                return CompilePreOp(generator, item);
            }
            if (node is UnaryNode.PreDecNode)
            {
                return CompilePreOp(generator, item);
            }

            if (node is UnaryNode.PostIncNode)
            {
                return CompilePostOp(generator, item);
            }
            if (node is UnaryNode.PostDecNode)
            {
                return CompilePostOp(generator, item);
            }

            throw new NotImplementedException();
        }
        private static Item CompileNewArray(ByteCodeGenerator generator, NewNode.NewArrayNode node)
        {
            var elemType = node.GetType(generator);
            var type = node.GetType(generator);

            foreach (var expression in node.Dimensions)
            {
                new ExpressionCompiler(expression).Compile(generator).Coerce(PrimativeTypes.Int).Load();

                type = new Array(type);
            }

            var ndims = (byte)node.Dimensions.Count;

            var elemcode = TypeCodeHelper.ArrayCode((type as Array).ArrayType);
            if (elemcode == 0 || (elemcode == 1 && ndims == 1))
            {
                generator.EmitAnewarray(generator.Manager.AddConstantClass(elemType), type);
            }
            else if (elemcode == 1)
            {
                generator.EmitMultianewarray(ndims, generator.Manager.AddConstantClass(type), type);
            }
            else
            {
                generator.EmitNewarray(elemcode, type);
            }

            return new StackItem(generator, type);
        }
        public static void BufferToString(ByteCodeGenerator generator, DefinedType sb)
        {
            var toString = sb.FindMethod(generator, "toString", null);
            if (toString == null) throw new InvalidOperationException();

            new MemberItem(generator, toString, false).Invoke();
        }
        public static void AppendStrings(ByteCodeGenerator generator, DefinedType sb, ExpressionNode node)
        {
            if (node is AdditiveNode)
            {
                var addNode = node as AdditiveNode;

                generator.Kill();
                var addType = new AdditiveCompiler(addNode).Compile(generator).Type;
                generator.Revive();

                if (addType.Name == BuiltinTypes.String.Name)
                {
                    AppendStrings(generator, sb, addNode.LeftChild.Child);
                    AppendStrings(generator, sb, addNode.RightChild.Child);

                    return;
                }
            }

            var item = new ExpressionCompiler(node).Compile(generator);

            var appendMethod = sb.FindMethod(generator, "append", new List<Type> { item.Type });
            if (appendMethod == null) throw new InvalidOperationException();

            item.Load();
            new MemberItem(generator, appendMethod, false).Invoke();
        }
        public Item Compile(ByteCodeGenerator generator)
        {
            var item = new ExpressionCompiler(expression).Compile(generator);

            if (type == null) return item;

            if (type.Primitive && item.Type.Primitive)
            {
                return item.Coerce(type);
            }

            if (item.Type.IsAssignableTo(type))
            {
                return item;
            }

            if (item.Type.Primitive && !type.Primitive)
            {
                // box!
                var primative = item.Type as PrimativeTypes.PrimativeType;

                return primative.Box(generator, item, type as DefinedType);
            }
            if (!item.Type.Primitive && type.Primitive)
            {
                // unbox!
                var primative = type as PrimativeTypes.PrimativeType;

                return primative.Unbox(generator, item);
            }

            throw new InvalidOperationException();
        }
        public static Method FindMethod(this DefinedType type, ByteCodeGenerator generator, string name, List<Type> args)
        {
            type.Resolve(generator.Manager.Imports);

            var argCount = args == null ? 0 : args.Count;
            var methods = (name == "<init>"
                ? ((Class)type).Constructors.Select(x => (Method)x)
                : type.Methods)
                    .Where(x => x.Name == name && x.Parameters.Count == argCount);

            if (args == null || argCount == 0)
            {
                return methods.SingleOrDefault();
            }

            var method = methods
                .Where(x => x.Parameters.Zip(args, (p, a) => a.IsAssignableTo(p.Type)).All(i => i))
                // find the method with the fewest casts
                .Select(
                    x =>
                    new
                        {
                            method = x,
                            casts = x.Parameters.Zip(args, (p, a) => a.GetDescriptor() == p.Type.GetDescriptor() ? 0 : 1).Sum()
                        })
                .OrderBy(x => x.casts)
                .Select(x => x.method)
                .FirstOrDefault();

            return method;
        }
        public override Type GetType(ByteCodeGenerator manager)
        {
            var l = LeftChild.GetType(manager, false, true);
            var r = RightChild.GetType(manager, false, true);

            return l.FindCommonType(r);
        }
 public Item Compile(ByteCodeGenerator generator)
 {
     if (node is AssignmentNode.NormalAssignNode)
     {
         return CompileAssign(generator);
     }
     return CompileAssignOp(generator);
 }
        public ConditionalItem(ByteCodeGenerator generator, OpCodeValue opCode, Chain trueChain, Chain falseChain)
            : base(generator, PrimativeTypes.Boolean)
        {
            OpCode = opCode;

            TrueJumps = trueChain;
            FalseJumps = falseChain;
        }
        private Item CompileAssign(ByteCodeGenerator generator)
        {
            var lhs = new ExpressionCompiler(node.Left).Compile(generator);
            var type = ClassLocator.Find(lhs.Type, generator.Manager.Imports);

            new TranslationCompiler(node.Right, type).Compile(generator).Load();

            return new AssignItem(generator, lhs);
        }
        public static void MakeStringBuffer(ByteCodeGenerator generator, Class sb)
        {
            var sbInit = (Method)sb.Constructors.First(x => x.Parameters.Count == 0);

            var sbIndex = generator.Manager.AddConstantClass(sb);

            generator.EmitNew(sbIndex, sb);
            generator.Emit(OpCodeValue.dup);

            new MemberItem(generator, sbInit, true).Invoke();
        }
Beispiel #18
0
        private static Item CompileNewClass(ByteCodeGenerator generator, NewNode.NewClassNode node)
        {
            node.Type = ClassLocator.Find(node.GetType(generator), generator.Manager.Imports);

            generator.Emit(OpCodeValue.@new, generator.Manager.AddConstantClass(node.GetType(generator) as DefinedType));
            generator.Emit(OpCodeValue.dup);

            new PrimaryCompiler(new PrimaryNode.TermMethodExpression { Identifier = "<init>", Arguments = node.Arguments }).Compile(generator, new StackItem(generator, node.GetType(generator)));

            return new StackItem(generator, node.GetType(generator));
        }
        public static Item StackItem(ByteCodeGenerator generator, Type type)
        {
            if (type.Primitive)
            {
                if (TypeCode(type) == ItemTypeCode.Void)
                {
                    return new VoidItem(generator);
                }
            }

            return new StackItem(generator, type);
        }
            public override Type GetType(ByteCodeGenerator manager)
            {
                var l = LeftChild.GetType(manager, false, true);
                var r = RightChild.GetType(manager, false, true);

                if (!l.Primitive || !r.Primitive)
                {
                    return BuiltinTypes.String;
                }

                return base.GetType(manager);
            }
Beispiel #21
0
        public Item Compile(ByteCodeGenerator generator)
        {
            if (node is NewNode.NewArrayNode)
            {
                return CompileNewArray(generator, node as NewNode.NewArrayNode);
            }
            if (node is NewNode.NewClassNode)
            {
                return CompileNewClass(generator, node as NewNode.NewClassNode);
            }

            throw new NotImplementedException();
        }
        private Item CompileAssignOp(ByteCodeGenerator generator)
        {
            var lType = new TranslateNode { Child = node.Left }.GetType(generator, false, true);
            var rType = node.Right.GetType(generator, false, true);

            var type = lType.FindCommonType(rType);

            Item lhs;
            if (lType.Name == BuiltinTypes.String.Name)
            {
                var sb = BuiltinTypes.StringBuilder;

                AdditiveCompiler.MakeStringBuffer(generator, sb);

                lhs = new ExpressionCompiler(node.Left).Compile(generator);
                if (lhs.Width() > 0)
                {
                    generator.Emit(OpCodeValue.dup_x1 + (byte)(3 * (lhs.Width() - 1)));
                }

                lhs.Load();

                AdditiveCompiler.AppendStrings(generator, sb, node.Left);
                AdditiveCompiler.AppendStrings(generator, sb, node.Right.Child);

                AdditiveCompiler.BufferToString(generator, sb);
            }
            else
            {
                lhs = new ExpressionCompiler(node.Left).Compile(generator);
                lhs.Duplicate();

                lhs.Coerce(type).Load();

                new TranslationCompiler(node.Right, type).Compile(generator).Load();
                if (node is AssignmentNode.AddAssignNode)
                {
                    AdditiveCompiler.CompileAddition(generator, type);
                }
                else if (node is AssignmentNode.MinusAssignNode)
                {
                    AdditiveCompiler.CompileSubtraction(generator, type);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            return new AssignItem(generator, lhs);
        }
        private void CompileSuperCall(ByteCodeGenerator generator, PrimaryNode.TermConstructorCallExpression call)
        {
            var target = call.IsSuper
                ? (PrimaryNode)new PrimaryNode.TermSuperExpression()
                : (PrimaryNode)new PrimaryNode.TermThisExpression();

            new PrimaryCompiler(
                    new PrimaryNode.TermFieldExpression
                    {
                        Child = target,
                        SecondChild = new PrimaryNode.TermMethodExpression { Identifier = "<init>", Arguments = call.Arguments }
                    }
            ).Compile(generator);
        }
        public Item Compile(ByteCodeGenerator generator)
        {
            var type = node.GetType(generator);

            if (!type.Primitive)
            {
                throw new InvalidOperationException();
            }

            new TranslationCompiler(node.LeftChild, type).Compile(generator).Load();
            new TranslationCompiler(node.RightChild, type).Compile(generator).Load();

            OpCodeValue opcode = CompileRelation(generator, type);

            return new ConditionalItem(generator, opcode);
        }
        public void Compile(ByteCodeGenerator generator)
        {
            var variable = generator.DefineVariable(node.Name, node.Type);

            if (node.Initialiser != null)
            {
                new AssignmentCompiler(
                    new AssignmentNode.NormalAssignNode
                    {
                        Left = new PrimaryNode.TermIdentifierExpression { Identifier = node.Name },
                        Right = new TranslateNode { Child = node.Initialiser }
                    }).Compile(generator);

                new LocalItem(generator, variable).Store();
            }
        }
        public Type GetType(ByteCodeGenerator manager, bool tryBox, bool tryUnBox)
        {
            var type = Child.GetType(manager);

            var primative = type as PrimativeTypes.PrimativeType;
            if (tryBox && primative != null)
            {
                return primative.BoxedType;
            }

            if (tryUnBox && !type.Primitive)
            {
                return PrimativeTypes.UnboxType(type);
            }

            return type;
        }
 public void Compile(ByteCodeGenerator generator)
 {
     foreach (MethodTreeNode node in tree)
     {
         if (node is StatementNode)
         {
             new StatementCompiler(node as StatementNode).Compile(generator);
         }
         else if (node is VarDeclarationNode)
         {
             new VarDeclarationCompiler(node as VarDeclarationNode).Compile(generator);
         }
         else
         {
             throw new NotImplementedException();
         }
     }
 }
Beispiel #28
0
        protected Item(ByteCodeGenerator generator, Type type)
        {
            Generator = generator;

            if (type is PlaceholderType)
            {
                type = ClassLocator.Find(type, generator.Manager.Imports);
            }

            var definedType = type as DefinedType;
            if (definedType != null)
            {
                definedType.Resolve(generator.Manager.Imports);
            }

            Type = type;
            TypeCode = TypeCodeHelper.TypeCode(type);
        }
        public Item Compile(ByteCodeGenerator generator)
        {
            if (node is UnaryOtherNode.UnaryCastNode)
            {
                var cast = node as UnaryOtherNode.UnaryCastNode;
                var type = cast.GetType(generator);

                return new TranslationCompiler(cast.Expression, type).Compile(generator).Load();
            }
            if (node is UnaryOtherNode.UnaryNotNode)
            {
                var not = node as UnaryOtherNode.UnaryNotNode;

                var item = new TranslationCompiler(not.Expression, PrimativeTypes.Boolean).Compile(generator).Conditional();

                return item.Negate();
            }

            throw new NotImplementedException();
        }
 private OpCodeValue CompileInt(ByteCodeGenerator generator)
 {
     if (node is RelationNode.LessThanEqNode)
     {
         return OpCodeValue.if_icmple;
     }
     if (node is RelationNode.GreaterThanEqNode)
     {
         return OpCodeValue.if_icmpge;
     }
     if (node is RelationNode.LessThanNode)
     {
         return OpCodeValue.if_icmplt;
     }
     if (node is RelationNode.GreaterThanNode)
     {
         return OpCodeValue.if_icmpgt;
     }
     throw new NotImplementedException();
 }