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 PrimaryCompiler(PrimaryNode node) { this.node = node; }
private static Item TryInstance(ByteCodeGenerator generator, Type type, PrimaryNode.TermIdentifierExpression id) { if (type is Array) { if (id.Identifier == "length") { generator.Emit(OpCodeValue.arraylength); return new StackItem(generator, PrimativeTypes.Int); } } var definedType = type as DefinedType; if (definedType == null) return null; // try instance Field field = definedType.Fields.FirstOrDefault(x => x.Name == id.Identifier); if (field == null) { if (type is Class && ((Class)type).Super != null) { definedType.Resolve(generator.Manager.Imports); return TryInstance(generator, ((Class)type).Super, id); } return null; } bool nonVirtual = field.Modifiers.HasFlag(Modifier.Private); bool isStatic = field.Modifiers.HasFlag(Modifier.Static); return isStatic ? new StaticItem(generator, field) : (Item)new MemberItem(generator, field, nonVirtual); }
private static LocalItem TryLocal(ByteCodeGenerator generator, PrimaryNode.TermIdentifierExpression id) { Variable localVariable = generator.GetVariable(id.Identifier); return localVariable != null ? new LocalItem(generator, localVariable) : null; }
private static ClassItem TryClass(ByteCodeGenerator generator, PrimaryNode.TermIdentifierExpression id) { var c = ClassLocator.Find(id.Identifier, generator.Manager.Imports); return c == null ? null : new ClassItem(generator, c); }
private static Item CompileMethod(ByteCodeGenerator generator, DefinedType parentType, PrimaryNode.TermMethodExpression id) { generator.Kill(); var args = id.Arguments.Select(parameter => new TranslationCompiler(parameter).Compile(generator).Type).ToList(); generator.Revive(); var method = parentType.FindMethod(generator, id.Identifier, args); if (method == null) throw new InvalidOperationException(); foreach (var arg in method.Parameters.Zip(id.Arguments, (dst, src) => new { dst, src })) { new TranslationCompiler(arg.src, arg.dst.Type).Compile(generator).Load(); } var isSuper = false; if (generator.Method.DeclaringType is Class) { isSuper = parentType == ((Class)generator.Method.DeclaringType).Super; } var item = method.Modifiers.HasFlag(Modifier.Static) ? (Item)new StaticItem(generator, method) : new MemberItem(generator, method, method.Name == "<init>" || isSuper); return item.Invoke(); }
private static Item CompileIdentifier(ByteCodeGenerator generator, Item scope, PrimaryNode.TermIdentifierExpression id) { if (scope == null) { // try local, instance, static, super, etc... Item item = TryLocal(generator, id); if (item != null) return item; item = TryInstance(generator, generator.Method.DeclaringType, id); if (item != null) { if (item is MemberItem) { new SelfItem(generator, generator.Method.DeclaringType, false).Load(); } return item; } item = TryClass(generator, id); if (item != null) return item; } else if (scope is SelfItem) { var self = scope as SelfItem; if (self.IsSuper) { // try super } else { Item item = TryInstance(generator, generator.Method.DeclaringType, id); if (item != null) return item; } } else if (scope is ClassItem) { var c = scope as ClassItem; Item item = TryInstance(generator, c.Type, id); if (item != null) return item; } else if (scope is LocalItem) { var c = scope as LocalItem; var item = TryInstance(generator, c.Type, id); if (item != null) return item; } throw new NotImplementedException(); }
private static Item CompileField(ByteCodeGenerator generator, Item scope, PrimaryNode.TermFieldExpression field) { var item = new PrimaryCompiler(field.Child).Compile(generator, scope); item.Load(); return new PrimaryCompiler(field.SecondChild).Compile(generator, item); }
private static Item CompileArray(ByteCodeGenerator generator, Item scope, PrimaryNode.TermArrayExpression array) { var item = new PrimaryCompiler(array.Child).Compile(generator, scope); item.Load(); new ExpressionCompiler(array.Index).Compile(generator).Load(); var result = item.Type as Array; return new IndexedItem(generator, result.ArrayType); }