protected override void TranslateAssignment(List<string> output, Assignment assignment) { output.Add(this.CurrentTabIndention); Expression target = assignment.Target; if (target is Variable && ((Variable)target).IsStatic) { output.Add("public static "); } Annotation typeAnnotation = target.GetAnnotation("type"); if (typeAnnotation != null) { CSharpPlatform csharpPlatform = (CSharpPlatform)this.Platform; string csharpType = csharpPlatform.GetTypeStringFromAnnotation(typeAnnotation.FirstToken, typeAnnotation.GetSingleArgAsString(null)); output.Add(csharpType); output.Add(" "); } this.TranslateExpression(output, target); output.Add(" "); output.Add(assignment.AssignmentOp); output.Add(" "); this.TranslateExpression(output, assignment.Value); output.Add(";"); output.Add(this.NL); }
protected override void TranslateAssignment(List<string> output, Assignment assignment) { output.Add(this.CurrentTabIndention); this.TranslateExpression(output, assignment.Target); output.Add(this.Shorten(" ")); output.Add(assignment.AssignmentOp); output.Add(this.Shorten(" ")); this.TranslateExpression(output, assignment.Value); output.Add(";" + this.NL); }
internal override IList<Executable> Resolve(Parser parser) { this.Expression = this.Expression.Resolve(parser); if (this.Expression == null) { return new Executable[0]; } if (this.Expression is Increment) { Increment inc = (Increment)this.Expression; Assignment output = new Assignment( inc.Root, inc.IncrementToken, inc.IsIncrement ? "+=" : "-=", new IntegerConstant(inc.IncrementToken, 1, this.FunctionOrClassOwner), this.FunctionOrClassOwner); return output.Resolve(parser); } return Listify(this); }
private void CompileAssignment(Parser parser, ByteBuffer buffer, Assignment assignment) { if (assignment.AssignmentOp == "=") { if (assignment.Target is Variable) { Variable varTarget = (Variable)assignment.Target; this.CompileExpression(parser, buffer, assignment.Value, true); int scopeId = varTarget.LocalScopeId; if (scopeId == -1) { throw new Exception(); // this should not happen. } buffer.Add(assignment.AssignmentOpToken, OpCode.ASSIGN_LOCAL, scopeId); } else if (assignment.Target is BracketIndex) { BracketIndex bi = (BracketIndex)assignment.Target; // TODO: optimization opportunity: special op code when index is a string or int constant. this.CompileExpression(parser, buffer, bi.Root, true); this.CompileExpression(parser, buffer, bi.Index, true); this.CompileExpression(parser, buffer, assignment.Value, true); buffer.Add(assignment.AssignmentOpToken, OpCode.ASSIGN_INDEX, 0); } else if (assignment.Target is DotStep) { DotStep dotStep = (DotStep)assignment.Target; if (dotStep.Root is ThisKeyword) { this.CompileExpression(parser, buffer, assignment.Value, true); buffer.Add(assignment.AssignmentOpToken, OpCode.ASSIGN_THIS_STEP, parser.GetId(dotStep.StepToken.Value)); } else { this.CompileExpression(parser, buffer, dotStep.Root, true); this.CompileExpression(parser, buffer, assignment.Value, true); buffer.Add(assignment.AssignmentOpToken, OpCode.ASSIGN_STEP, parser.GetId(dotStep.StepToken.Value), 0); } } else if (assignment.Target is FieldReference) { this.CompileExpression(parser, buffer, assignment.Value, true); FieldReference fieldReference = (FieldReference)assignment.Target; if (fieldReference.Field.IsStaticField) { buffer.Add( assignment.AssignmentOpToken, OpCode.ASSIGN_STATIC_FIELD, ((ClassDefinition)fieldReference.Field.FunctionOrClassOwner).ClassID, fieldReference.Field.StaticMemberID); } else { // TODO: "this.foo = value" throw new NotImplementedException(); } } else { throw new Exception("This shouldn't happen."); } } else { BinaryOps op = this.ConvertOpString(assignment.AssignmentOpToken); if (assignment.Target is Variable) { Variable varTarget = (Variable)assignment.Target; int scopeId = varTarget.LocalScopeId; if (scopeId == -1) { throw new Exception(); // all variables should have local ID's allocated or errors thrown by now. } this.CompileExpression(parser, buffer, assignment.Value, true); buffer.Add(assignment.AssignmentOpToken, OpCode.BINARY_OP, (int)op); buffer.Add(assignment.Target.FirstToken, OpCode.ASSIGN_LOCAL, scopeId); throw new NotImplementedException(); // TODO: redo this } else if (assignment.Target is DotStep) { DotStep dotExpr = (DotStep)assignment.Target; int stepId = parser.GetId(dotExpr.StepToken.Value); this.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, stepId); this.CompileExpression(parser, buffer, assignment.Value, true); buffer.Add(assignment.AssignmentOpToken, OpCode.BINARY_OP, (int)op); if (dotExpr.Root is ThisKeyword) { buffer.Add(assignment.AssignmentOpToken, OpCode.ASSIGN_THIS_STEP, stepId); } else { buffer.Add(assignment.AssignmentOpToken, OpCode.ASSIGN_STEP, stepId, 0); } } else if (assignment.Target is BracketIndex) { BracketIndex indexExpr = (BracketIndex)assignment.Target; this.CompileExpression(parser, buffer, indexExpr.Root, true); this.CompileExpression(parser, buffer, indexExpr.Index, true); buffer.Add(null, OpCode.DUPLICATE_STACK_TOP, 2); buffer.Add(indexExpr.BracketToken, OpCode.INDEX); this.CompileExpression(parser, buffer, assignment.Value, true); buffer.Add(assignment.AssignmentOpToken, OpCode.BINARY_OP, (int)op); buffer.Add(assignment.AssignmentOpToken, OpCode.ASSIGN_INDEX, 0); } else { throw new ParserException(assignment.AssignmentOpToken, "Assignment is not allowed on this sort of expression."); } } }
private void CompileClass(Parser parser, ByteBuffer buffer, ClassDefinition classDefinition) { bool hasStaticFieldsWithStartingValues = classDefinition.Fields .Where<FieldDeclaration>(fd => fd.IsStaticField && fd.DefaultValue != null && !(fd.DefaultValue is NullConstant)) .Count() > 0; if (hasStaticFieldsWithStartingValues) { if (classDefinition.StaticConstructor == null) { classDefinition.StaticConstructor = new ConstructorDefinition(null, new Token[0], new Expression[0], new Expression[0], new Executable[0], null, classDefinition); } List<Executable> staticFieldInitializers = new List<Executable>(); foreach (FieldDeclaration fd in classDefinition.Fields) { if (fd.IsStaticField && fd.DefaultValue != null && !(fd.DefaultValue is NullConstant)) { Executable assignment = new Assignment(new FieldReference(fd.FirstToken, fd, classDefinition), fd.NameToken, "=", fd.DefaultValue, classDefinition); staticFieldInitializers.Add(assignment); } } staticFieldInitializers.AddRange(classDefinition.StaticConstructor.Code); classDefinition.StaticConstructor.Code = staticFieldInitializers.ToArray(); } if (classDefinition.StaticConstructor != null) { // All static field initializers are added here. this.CompileConstructor(parser, buffer, classDefinition.StaticConstructor); } this.CompileConstructor(parser, buffer, classDefinition.Constructor); foreach (FunctionDefinition fd in classDefinition.Methods) { int pc = buffer.Size; fd.FinalizedPC = pc; this.CompileFunctionDefinition(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<FieldDeclaration>(fd => fd.IsStaticField).Count(); FieldDeclaration[] regularFields = classDefinition.Fields.Where<FieldDeclaration>(fd => !fd.IsStaticField).ToArray(); FunctionDefinition[] regularMethods = classDefinition.Methods.Where<FunctionDefinition>(fd => !fd.IsStaticMethod).ToArray(); List<int> members = new List<int>(); List<FieldDeclaration> fieldsWithComplexValues = new List<FieldDeclaration>(); foreach (FieldDeclaration fd in regularFields) { int memberId = fd.MemberID; int fieldNameId = parser.GetId(fd.NameToken.Value); int initInstruction; int literalId = 0; if (fd.DefaultValue is ListDefinition && ((ListDefinition)fd.DefaultValue).Items.Length == 0) { initInstruction = 1; } else if (fd.DefaultValue is DictionaryDefinition && ((DictionaryDefinition)fd.DefaultValue).Keys.Length == 0) { initInstruction = 2; } else { 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}); } 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. It's just here to keep spacing consistent. }); } ByteBuffer initializer = null; if (fieldsWithComplexValues.Count > 0) { initializer = new ByteBuffer(); foreach (FieldDeclaration complexField in fieldsWithComplexValues) { this.CompileExpression(parser, initializer, complexField.DefaultValue, true); initializer.Add(complexField.FirstToken, OpCode.ASSIGN_THIS_STEP, complexField.MemberID); } initializer.Add(null, OpCode.RETURN, 0); } List<int> args = new List<int>() { classId, baseClassId, nameId, constructorId, initializer == null ? 0 : initializer.Size, // jump amount after initialization staticConstructorId, staticFieldCount, }; args.AddRange(members); buffer.Add(classDefinition.FirstToken, OpCode.CLASS_DEFINITION, args.ToArray()); if (initializer != null) { buffer.Concat(initializer); } }
protected abstract void TranslateAssignment(List<string> output, Assignment assignment);