Exemple #1
0
        internal override Expression ResolveNames(Parser parser)
        {
            if (this.Name == "$$$")
            {
                throw new ParserException(this.FirstToken, "Core function invocations cannot stand alone and must be immediately invoked.");
            }

            if (this.Name.StartsWith("$$"))
            {
                return(new LibraryFunctionReference(this.FirstToken, this.Name.Substring(2), this.Owner));
            }

            if (this.Name == "this" || this.Name == "base")
            {
                TopLevelConstruct container = parser.CurrentCodeContainer;

                if (container is FunctionDefinition)
                {
                    FunctionDefinition funcDef = (FunctionDefinition)this.Owner;
                    if (funcDef.IsStaticMethod)
                    {
                        throw new ParserException(this.FirstToken, "Cannot use '" + this.Name + "' in a static method");
                    }

                    if (funcDef.Owner == null)
                    {
                        throw new ParserException(this.FirstToken, "Cannot use '" + this.Name + "' in a function that isn't a class method.");
                    }
                }

                if (container is FieldDeclaration)
                {
                    if (((FieldDeclaration)container).IsStaticField)
                    {
                        throw new ParserException(this.FirstToken, "Cannot use '" + this.Name + "' in a static field value.");
                    }
                }

                if (container is ConstructorDefinition)
                {
                    ConstructorDefinition constructor = (ConstructorDefinition)container;
                    if (constructor == ((ClassDefinition)constructor.Owner).StaticConstructor) // TODO: This check is silly. Add an IsStatic field to ConstructorDefinition.
                    {
                        throw new ParserException(this.FirstToken, "Cannot use '" + this.Name + "' in a static constructor.");
                    }
                }

                if (this.Name == "this")
                {
                    return(new ThisKeyword(this.FirstToken, this.Owner));
                }
                return(new BaseKeyword(this.FirstToken, this.Owner));
            }

            TopLevelConstruct exec = this.Owner.FileScope.FileScopeEntityLookup.DoLookup(this.Name, this.Owner);

            if (exec != null)
            {
                return(Resolver.ConvertStaticReferenceToExpression(exec, this.FirstToken, this.Owner));
            }

            return(this);
        }
Exemple #2
0
        internal override Expression Resolve(Parser parser)
        {
            string className = this.NameToken.Value;

            if (parser.IsTranslateMode)
            {
                StructDefinition structDefinition = parser.GetStructDefinition(className);

                if (structDefinition != null)
                {
                    if (this.Args.Length != structDefinition.Fields.Length)
                    {
                        throw new ParserException(this.FirstToken, "Args length did not match struct field count for '" + structDefinition.Name.Value + "'.");
                    }

                    StructInstance si = new StructInstance(this.FirstToken, this.NameToken, this.Args, this.FunctionOrClassOwner);
                    si = (StructInstance)si.Resolve(parser);
                    return(si);
                }
            }

            for (int i = 0; i < this.Args.Length; ++i)
            {
                this.Args[i] = this.Args[i].Resolve(parser);
            }

            if (this.Class == null)
            {
                throw new ParserException(this.FirstToken, "No class named '" + this.Name + "'");
            }

            if (this.Class.StaticToken != null)
            {
                throw new ParserException(this.FirstToken, "Cannot instantiate a static class.");
            }

            ConstructorDefinition cons = this.Class.Constructor;

            if (cons.PrivateAnnotation != null)
            {
                if (this.Class != this.FunctionOrClassOwner.FunctionOrClassOwner)
                {
                    string errorMessage = "The constructor for " + this.Class.NameToken.Value + " is private and cannot be invoked from outside the class.";
                    if (cons.PrivateAnnotation.Args.Length > 0)
                    {
                        StringConstant stringMessage = cons.PrivateAnnotation.Args[0] as StringConstant;
                        if (stringMessage != null)
                        {
                            errorMessage += " " + stringMessage.Value.Trim();
                        }
                    }

                    throw new ParserException(this.FirstToken, errorMessage);
                }
            }

            if (this.Args.Length < cons.MinArgCount || this.Args.Length > cons.MaxArgCount)
            {
                string message = "This constructor has the wrong number of arguments. ";
                if (cons.MinArgCount == cons.MaxArgCount)
                {
                    message += "Expected " + cons.MinArgCount + " but found " + this.Args.Length;
                }
                else if (this.Args.Length < cons.MinArgCount)
                {
                    message += " At least " + cons.MinArgCount + " are required but found only " + this.Args.Length + ".";
                }
                else
                {
                    message += " At most " + cons.MaxArgCount + " are allowed but found " + this.Args.Length + ".";
                }
                throw new ParserException(this.FirstToken, message);
            }

            return(this);
        }
Exemple #3
0
        internal override Expression Resolve(Parser parser)
        {
            for (int i = 0; i < this.Args.Length; ++i)
            {
                this.Args[i] = this.Args[i].Resolve(parser);
            }

            if (this.Class == null)
            {
                throw new ParserException(this.FirstToken, "No class named '" + this.Name + "'");
            }

            if (this.Class.StaticToken != null)
            {
                throw new ParserException(this.FirstToken, "Cannot instantiate a static class.");
            }

            ConstructorDefinition cons = this.Class.Constructor;

            if (cons.PrivateAnnotation != null)
            {
                bool isValidUsage =
                    this.Class == this.FunctionOrClassOwner ||
                    this.Class == this.FunctionOrClassOwner.FunctionOrClassOwner;

                if (!isValidUsage)
                {
                    string errorMessage = "The constructor for " + this.Class.NameToken.Value + " is private and cannot be invoked from outside the class.";
                    if (cons.PrivateAnnotation.Args.Length > 0)
                    {
                        StringConstant stringMessage = cons.PrivateAnnotation.Args[0] as StringConstant;
                        if (stringMessage != null)
                        {
                            errorMessage += " " + stringMessage.Value.Trim();
                        }
                    }

                    throw new ParserException(this.FirstToken, errorMessage);
                }
            }

            if (this.Args.Length < cons.MinArgCount || this.Args.Length > cons.MaxArgCount)
            {
                string message = "This constructor has the wrong number of arguments. ";
                if (cons.MinArgCount == cons.MaxArgCount)
                {
                    message += "Expected " + cons.MinArgCount + " but found " + this.Args.Length;
                }
                else if (this.Args.Length < cons.MinArgCount)
                {
                    message += " At least " + cons.MinArgCount + " are required but found only " + this.Args.Length + ".";
                }
                else
                {
                    message += " At most " + cons.MaxArgCount + " are allowed but found " + this.Args.Length + ".";
                }
                throw new ParserException(this.FirstToken, message);
            }

            return(this);
        }
Exemple #4
0
		private void CompileConstructor(Parser parser, ByteBuffer buffer, ConstructorDefinition constructor)
		{
			// TODO: throw parser exception in the resolver if a return appears with any value

			ByteBuffer tBuffer = new ByteBuffer();

			ClassDefinition cd = (ClassDefinition)constructor.FunctionOrClassOwner;

			List<int> offsetsForOptionalArgs = new List<int>();
			this.CompileFunctionArgs(parser, tBuffer, constructor.ArgNames, constructor.DefaultValues, offsetsForOptionalArgs);

			int minArgs = 0;
			int maxArgs = constructor.ArgNames.Length;
			for (int i = 0; i < constructor.ArgNames.Length; ++i)
			{
				if (constructor.DefaultValues[i] == null)
				{
					minArgs++;
				}
				else
				{
					break;
				}
			}

			if (constructor.BaseToken != null)
			{
				this.CompileExpressionList(parser, tBuffer, constructor.BaseArgs, true);
				tBuffer.Add(
					constructor.BaseToken,
					OpCode.CALL_FUNCTION,
					(int)FunctionInvocationType.BASE_CONSTRUCTOR,
					constructor.BaseArgs.Length,
					cd.BaseClass.Constructor.FunctionID,
					0,
					cd.BaseClass.ClassID);
			}

			this.Compile(parser, tBuffer, constructor.Code);
			tBuffer.Add(null, OpCode.RETURN, 0);

			bool isStatic = constructor == cd.StaticConstructor;

			List<int> args = new List<int>()
			{
				constructor.FunctionID,
				-1,
				minArgs,
				maxArgs,
				isStatic ? 4 : 3,
				cd.ClassID,
				constructor.LocalScopeSize,
				tBuffer.Size,
				offsetsForOptionalArgs.Count,
			};

			args.AddRange(offsetsForOptionalArgs);

			buffer.Add(constructor.FirstToken, OpCode.FUNCTION_DEFINITION, args.ToArray());
			buffer.Concat(tBuffer);
		}