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); } }
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(); }
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); }
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(); } } }
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(); }