Beispiel #1
0
		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);
		}
Beispiel #2
0
		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);
		}
Beispiel #4
0
		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.");
				}
			}
		}
Beispiel #5
0
		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);
			}
		}
Beispiel #6
0
		protected abstract void TranslateAssignment(List<string> output, Assignment assignment);