Beispiel #1
0
        public FunctionDefinition ParseFunctionDefinition(TokenStream tokens)
        {
            PType returnType = PType.Parse(tokens);
            Token nameToken  = EnsureTokenIsValidName(tokens.Pop(), "Expected function name");

            tokens.PopExpected("(");
            List <PType> argTypes = new List <PType>();
            List <Token> argNames = new List <Token>();

            while (!tokens.PopIfPresent(")"))
            {
                if (argTypes.Count > 0)
                {
                    tokens.PopExpected(",");
                }
                argTypes.Add(PType.Parse(tokens));
                argNames.Add(EnsureTokenIsValidName(tokens.Pop(), "Invalid function arg name"));
            }
            FunctionDefinition funcDef = new FunctionDefinition(nameToken, returnType, argTypes, argNames, this.context, null);

            this.currentCodeOwner = funcDef;
            List <Executable> code = this.ParseCodeBlock(tokens, true);

            this.currentCodeOwner = null;
            funcDef.Code          = code.ToArray();
            return(funcDef);
        }
Beispiel #2
0
 public ThisExpression(Token token, ICompilationEntity owner)
     : base(token, owner)
 {
     if (owner == null)
     {
         throw new Exception();
     }
 }
Beispiel #3
0
 public VariableScope(ICompilationEntity functionDef)
 {
     if (!(functionDef is FunctionDefinition) && !(functionDef is ConstructorDefinition))
     {
         throw new System.InvalidOperationException();
     }
     this.RootFunctionOrConstructorDefinition = functionDef;
 }
Beispiel #4
0
 public Variable(Token token, ICompilationEntity owner) : base(token, owner)
 {
     this.IsFunctionInvocation = false;
     this.ApplyPrefix          = true;
     if (BANNED_NAMES.Contains(token.Value))
     {
         throw new ParserException(token, "The name '" + token.Value + "' is reserved for some platforms and cannot be used.");
     }
 }
Beispiel #5
0
        public DependencyNamespaceReference(Token firstToken, PastelCompiler dep, ICompilationEntity owner)
            : base(firstToken, owner)
        {
            if (dep == null)
            {
                throw new ParserException(firstToken, "Could not resolve namespace: " + this.FirstToken.Value);
            }

            this.Scope = dep;
        }
Beispiel #6
0
        public static InlineConstant Of(object value, ICompilationEntity owner)
        {
            Token dummyToken = Token.CreateDummyToken(value.ToString());

            if (value is int)
            {
                return((InlineConstant) new InlineConstant(PType.INT, dummyToken, value, owner).ResolveType(null, null));
            }

            throw new NotImplementedException();
        }
Beispiel #7
0
        internal override Expression ResolveType(VariableScope varScope, PastelCompiler compiler)
        {
            this.Root = this.Root.ResolveType(varScope, compiler);

            PType rootType = this.Root.ResolvedType;

            if (rootType.IsStructOrClass)
            {
                string fieldName = this.FieldName.Value;
                rootType.FinalizeType(compiler);
                if (rootType.IsStruct)
                {
                    this.StructType = rootType.StructDef;
                    int fieldIndex;
                    if (!this.StructType.FlatFieldIndexByName.TryGetValue(fieldName, out fieldIndex))
                    {
                        throw new ParserException(this.FieldName, "The struct '" + this.StructType.NameToken.Value + "' does not have a field called '" + fieldName + "'.");
                    }
                    this.ResolvedType = this.StructType.FlatFieldTypes[fieldIndex];
                }
                else
                {
                    this.ClassType = rootType.ClassDef;
                    if (!this.ClassType.Members.ContainsKey(this.FieldName.Value))
                    {
                        throw new ParserException(this.FieldName, "The class '" + this.ClassType.NameToken.Value + "' does not have a member called '" + fieldName + "'.");
                    }

                    ICompilationEntity ce = this.ClassType.Members[fieldName];
                    if (ce is FieldDefinition fd)
                    {
                        this.ResolvedType = fd.FieldType;
                    }
                    else
                    {
                        FunctionDefinition func = (FunctionDefinition)ce;
                        this.ResolvedType = PType.FunctionOf(this.FieldName, func.ReturnType, func.ArgTypes);
                    }
                }
                return(this);
            }

            this.CoreFunctionId = this.DetermineCoreFunctionId(this.Root.ResolvedType, this.FieldName.Value);
            if (this.CoreFunctionId != CoreFunction.NONE)
            {
                CoreFunctionReference cfr = new CoreFunctionReference(this.FirstToken, this.CoreFunctionId, this.Root, this.Owner);
                cfr.ResolvedType = new PType(this.Root.FirstToken, null, "@CoreFunc");
                return(cfr);
            }

            throw new NotImplementedException();
        }
Beispiel #8
0
 private PythonFakeSwitchStatement(
     string functionName,
     int switchId,
     int defaultChunkId,
     Dictionary <InlineConstant, int> expressionsToChunkIds,
     Dictionary <int, Executable[]> chunkIdsToCode,
     ICompilationEntity owner)
 {
     this.owner                 = owner;
     this.functionName          = functionName;
     this.switchId              = switchId;
     this.DefaultId             = defaultChunkId;
     this.expressionsToChunkIds = expressionsToChunkIds;
     this.chunkIdsToCode        = chunkIdsToCode;
 }
Beispiel #9
0
        public static PythonFakeSwitchStatement Build(SwitchStatement switchStatement, int switchId, string functionName)
        {
            ICompilationEntity owner = switchStatement.Condition.Owner;
            Dictionary <InlineConstant, int> expressionToId = new Dictionary <InlineConstant, int>();
            Dictionary <int, Executable[]>   codeById       = new Dictionary <int, Executable[]>();
            int?nullableDefaultId = null;

            Executable[] defaultCode = null;
            for (int i = 0; i < switchStatement.Chunks.Length; ++i)
            {
                SwitchStatement.SwitchChunk chunk = switchStatement.Chunks[i];
                int          currentId            = i;
                Expression[] cases = chunk.Cases;
                for (int j = 0; j < cases.Length; ++j)
                {
                    InlineConstant caze = (InlineConstant)cases[j];
                    if (caze == null)
                    {
                        nullableDefaultId = currentId;
                        defaultCode       = chunk.Code;
                    }
                    else
                    {
                        expressionToId[caze] = currentId;
                    }
                }

                codeById[currentId] = chunk.Code;
            }

            int defaultId;

            if (nullableDefaultId != null)
            {
                defaultId = nullableDefaultId.Value;
                if (!codeById.ContainsKey(defaultId))
                {
                    codeById[defaultId] = defaultCode;
                }
            }
            else
            {
                defaultId           = codeById.Count;
                codeById[defaultId] = new Executable[0];
            }

            return(new PythonFakeSwitchStatement(functionName, switchId, defaultId, expressionToId, codeById, owner));
        }
Beispiel #10
0
        public EnumDefinition ParseEnumDefinition(TokenStream tokens)
        {
            Token          enumToken = tokens.PopExpected("enum");
            Token          nameToken = EnsureTokenIsValidName(tokens.Pop(), "Invalid name for an enum.");
            EnumDefinition enumDef   = new EnumDefinition(enumToken, nameToken, this.context);

            this.currentCodeOwner = enumDef;
            List <Token>      valueTokens      = new List <Token>();
            List <Expression> valueExpressions = new List <Expression>();

            tokens.PopExpected("{");
            bool first = true;

            while (!tokens.PopIfPresent("}"))
            {
                if (!first)
                {
                    tokens.PopExpected(",");
                }
                else
                {
                    first = false;
                }

                if (tokens.PopIfPresent("}"))
                {
                    break;
                }

                Token valueToken = EnsureTokenIsValidName(tokens.Pop(), "Invalid name for a enum value.");
                valueTokens.Add(valueToken);
                if (tokens.PopIfPresent("="))
                {
                    Expression value = ParseExpression(tokens);
                    valueExpressions.Add(value);
                }
                else
                {
                    valueExpressions.Add(null);
                }
            }

            enumDef.InitializeValues(valueTokens, valueExpressions);
            this.currentCodeOwner = null;
            return(enumDef);
        }
Beispiel #11
0
        internal override void ResolveTypes(VariableScope varScope, PastelCompiler compiler)
        {
            // TODO: the variable scope should NOT be the messenger of this information.
            ICompilationEntity ce = varScope.RootFunctionOrConstructorDefinition;
            FunctionDefinition fd = ce as FunctionDefinition;

            if (fd != null)
            {
                if (this.Expression != null)
                {
                    this.Expression = this.Expression.ResolveType(varScope, compiler);
                    if (!PType.CheckReturnType(compiler, fd.ReturnType, this.Expression.ResolvedType))
                    {
                        throw new ParserException(this.Expression.FirstToken, "This expression is not the expected return type of this function.");
                    }
                }
                else
                {
                    if (!fd.ReturnType.IsIdentical(compiler, PType.VOID))
                    {
                        throw new ParserException(this.FirstToken, "Must return a value in this function.");
                    }
                }
            }
            else // constructors
            {
                if (this.Expression == null)
                {
                    // This is fine.
                }
                else
                {
                    // This isn't.
                    throw new ParserException(this.FirstToken, "You cannot return a value from a constructor.");
                }
            }
        }
Beispiel #12
0
        public ClassDefinition ParseClassDefinition(TokenStream tokens)
        {
            Token           classToken    = tokens.PopExpected("class");
            Token           nameToken     = tokens.PopIdentifier();
            ClassDefinition cd            = new ClassDefinition(this.context, classToken, nameToken);
            List <Token>    inheritTokens = new List <Token>();

            if (tokens.PopIfPresent(":"))
            {
                while (!tokens.IsNext("{"))
                {
                    if (inheritTokens.Count > 0)
                    {
                        tokens.PopExpected(",");
                    }
                    inheritTokens.Add(tokens.PopIdentifier());
                }
            }
            cd.InheritTokens = inheritTokens.ToArray();
            tokens.PopExpected("{");

            Dictionary <string, ICompilationEntity> members = new Dictionary <string, ICompilationEntity>();

            while (!tokens.PopIfPresent("}"))
            {
                string next = tokens.PeekValue();
                if (next == "constructor")
                {
                    if (cd.Constructor != null)
                    {
                        throw new ParserException(tokens.Peek(), "Only one constructor is permitted per class.");
                    }

                    Token constructorToken = tokens.PopExpected("constructor");
                    tokens.PopExpected("(");
                    List <PType> argTypes = new List <PType>();
                    List <Token> argNames = new List <Token>();
                    while (!tokens.PopIfPresent(")"))
                    {
                        if (argTypes.Count > 0)
                        {
                            tokens.PopExpected(",");
                        }
                        argTypes.Add(PType.Parse(tokens));
                        argNames.Add(tokens.PopIdentifier());
                    }
                    cd.Constructor        = new ConstructorDefinition(this.context, constructorToken, argTypes, argNames, cd);
                    this.currentCodeOwner = cd.Constructor;
                    cd.Constructor.Code   = this.ParseCodeBlock(tokens, true).ToArray();
                }
                else
                {
                    ICompilationEntity entity;
                    string             entityName;
                    PType memberType = PType.TryParse(tokens);
                    Token memberName = tokens.PopIdentifier();
                    bool  isMethod   = tokens.IsNext("(");
                    if (isMethod)
                    {
                        tokens.PopExpected("(");
                        List <PType> argTypes = new List <PType>();
                        List <Token> argNames = new List <Token>();
                        while (!tokens.PopIfPresent(")"))
                        {
                            if (argTypes.Count > 0)
                            {
                                tokens.PopExpected(",");
                            }
                            argTypes.Add(PType.Parse(tokens));
                            argNames.Add(tokens.PopIdentifier());
                        }
                        FunctionDefinition fd = new FunctionDefinition(memberName, memberType, argTypes, argNames, this.context, cd);
                        this.currentCodeOwner = fd;
                        List <Executable> code = this.ParseCodeBlock(tokens, true);
                        fd.Code    = code.ToArray();
                        entity     = fd;
                        entityName = fd.Name;
                    }
                    else
                    {
                        FieldDefinition fd = new FieldDefinition(this.context, memberType, memberName, cd);
                        this.currentCodeOwner = fd;
                        Expression initialValue = null;
                        if (tokens.PopIfPresent("="))
                        {
                            initialValue = this.ParseExpression(tokens);
                        }
                        else
                        {
                            if (memberType.IsNullable)
                            {
                                initialValue = new InlineConstant(memberType, memberName, null, cd);
                            }
                            else
                            {
                                switch (memberType.RootValue)
                                {
                                case "double": initialValue = new InlineConstant(memberType, memberName, 0.0, cd); break;

                                case "int": initialValue = new InlineConstant(memberType, memberName, 0, cd); break;

                                case "string": initialValue = new InlineConstant(memberType, memberName, null, cd); break;

                                default: throw new NotImplementedException();
                                }
                            }
                        }
                        tokens.PopExpected(";");
                        fd.Value   = initialValue;
                        entity     = fd;
                        entityName = fd.NameToken.Value;
                    }

                    if (members.ContainsKey(entityName))
                    {
                        throw new ParserException(memberName,
                                                  "There are conflicting members in the class '" + cd.NameToken.Value + "' for the name '" + entityName + "'.");
                    }

                    members[entityName] = entity;
                }
            }

            cd.AddMembers(members);

            return(cd);
        }
Beispiel #13
0
 public CoreFunctionReference(Token firstToken, CoreFunction coreFunctionId, ICompilationEntity owner) : this(firstToken, coreFunctionId, null, owner)
 {
 }
Beispiel #14
0
 public NamespaceReference(Token firstToken, ICompilationEntity owner) : base(firstToken, owner)
 {
 }
Beispiel #15
0
 public CompileTimeFunctionReference(Token atToken, Token nameToken, ICompilationEntity owner) : base(atToken, owner)
 {
     this.NameToken = nameToken;
 }
Beispiel #16
0
 public CoreFunctionInvocation(Token firstToken, CoreFunction function, IList <Expression> args, ICompilationEntity owner) : base(firstToken, owner)
 {
     this.Function = function;
     this.Args     = args.ToArray();
 }
Beispiel #17
0
 public ConstructorInvocation(Token firstToken, PType type, IList <Expression> args, ICompilationEntity owner)
     : base(firstToken, owner)
 {
     this.Type         = type;
     this.Args         = args.ToArray();
     this.ResolvedType = type;
 }
 public ExtensibleFunctionReference(Token token, string name, ICompilationEntity owner) : base(token, owner)
 {
     this.Name = name;
 }
Beispiel #19
0
        public CoreFunctionReference(Token firstToken, CoreFunction coreFunctionId, Expression context, ICompilationEntity owner) : base(firstToken, owner)
        {
            this.CoreFunctionId = coreFunctionId;
            this.Context        = context;

            this.ReturnType         = CoreFunctionUtil.GetCoreFunctionReturnType(this.CoreFunctionId);
            this.ArgTypes           = CoreFunctionUtil.GetCoreFunctionArgTypes(this.CoreFunctionId);
            this.ArgTypesIsRepeated = CoreFunctionUtil.GetCoreFunctionIsArgTypeRepeated(this.CoreFunctionId);
        }
Beispiel #20
0
 public CoreFunctionInvocation(Token firstToken, CoreFunction function, Expression context, IList <Expression> args, ICompilationEntity owner)
     : this(firstToken, function, PushInFront(context, args), owner)
 {
 }
Beispiel #21
0
 public InlineConstant CloneWithNewTokenAndOwner(Token token, ICompilationEntity owner)
 {
     return(new InlineConstant(this.Type, token, this.Value, owner));
 }
Beispiel #22
0
 public Expression(Token firstToken, ICompilationEntity owner)
 {
     this.FirstToken = firstToken;
     this.Owner      = owner;
 }
Beispiel #23
0
 public FunctionReference(Token firstToken, FunctionDefinition functionDefinition, ICompilationEntity owner) : base(firstToken, owner)
 {
     this.Function = functionDefinition;
     this.IsLibraryScopedFunction = false;
 }
Beispiel #24
0
 public EnumReference(Token firstToken, EnumDefinition enumDef, ICompilationEntity owner) : base(firstToken, owner)
 {
     this.EnumDef = enumDef;
 }
Beispiel #25
0
 public VariableScope(VariableScope parent)
 {
     this.parent = parent;
     this.RootFunctionOrConstructorDefinition = parent.RootFunctionOrConstructorDefinition;
 }
Beispiel #26
0
 public InlineConstant(PType type, Token firstToken, object value, ICompilationEntity owner) : base(firstToken, owner)
 {
     this.Type         = type;
     this.ResolvedType = type;
     this.Value        = value;
 }
 public ConstructorReference(Token newToken, PType type, ICompilationEntity owner) : base(newToken, owner)
 {
     this.TypeToConstruct = type;
 }