Example #1
0
 internal override Expression ResolveType(VariableScope varScope, PastelCompiler compiler)
 {
     this.Expression = this.Expression.ResolveType(varScope, compiler);
     if (!this.Expression.ResolvedType.IsIdentical(PType.INT))
     {
         throw new ParserException(this.IncrementToken, "++ and -- can only be applied to integer types.");
     }
     this.ResolvedType = PType.INT;
     return(this);
 }
Example #2
0
        public override Executable ResolveNamesAndCullUnusedCode(PastelCompiler compiler)
        {
            if (this.Value == null)
            {
                throw new ParserException(this.FirstToken, "Cannot have variable declaration without a value.");
            }
            this.Value = this.Value.ResolveNamesAndCullUnusedCode(compiler);

            return(this);
        }
        internal override void ResolveTypes(VariableScope varScope, PastelCompiler compiler)
        {
            this.Value = this.Value.ResolveType(varScope, compiler);

            if (!PType.CheckAssignment(this.Type, this.Value.ResolvedType))
            {
                throw new ParserException(this.Value.FirstToken, "Cannot assign this type to a " + this.Type);
            }

            varScope.DeclareVariables(this.VariableNameToken, this.Type);
        }
Example #4
0
        internal override void ResolveTypes(VariableScope varScope, PastelCompiler compiler)
        {
            // This gets compiled as a wihle loop with the init added before the loop, so it should go in the same variable scope.
            // The implication is that multiple declarations in the init for successive loops will collide.
            Executable.ResolveTypes(this.InitCode, varScope, compiler);
            this.Condition = this.Condition.ResolveType(varScope, compiler);
            Executable.ResolveTypes(this.StepCode, varScope, compiler);
            VariableScope innerScope = new VariableScope(varScope);

            Executable.ResolveTypes(this.Code, innerScope, compiler);
        }
Example #5
0
        internal override void ResolveTypes(VariableScope varScope, PastelCompiler compiler)
        {
            this.Condition = this.Condition.ResolveType(varScope, compiler);
            if (this.Condition.ResolvedType.RootValue != "bool")
            {
                throw new ParserException(this.Condition.FirstToken, "Only booleans can be used in if statements.");
            }

            Executable.ResolveTypes(this.IfCode, new VariableScope(varScope), compiler);
            Executable.ResolveTypes(this.ElseCode, new VariableScope(varScope), compiler);
        }
Example #6
0
        internal override Expression ResolveType(VariableScope varScope, PastelCompiler compiler)
        {
            PType type = varScope.GetTypeOfVariable(this.Name);

            this.ResolvedType = type;
            if (type == null)
            {
                throw new ParserException(this.FirstToken, "The variable '" + this.Name + "' is not defined.");
            }

            return(this);
        }
Example #7
0
        public override Executable ResolveNamesAndCullUnusedCode(PastelCompiler compiler)
        {
            this.InitCode  = Executable.ResolveNamesAndCullUnusedCodeForBlock(this.InitCode, compiler).ToArray();
            this.Condition = this.Condition.ResolveNamesAndCullUnusedCode(compiler);
            this.StepCode  = Executable.ResolveNamesAndCullUnusedCodeForBlock(this.StepCode, compiler).ToArray();

            // TODO: check Condition for falseness

            this.Code = Executable.ResolveNamesAndCullUnusedCodeForBlock(this.Code, compiler).ToArray();

            return(this);
        }
Example #8
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();
        }
Example #9
0
        public void ResolveTypes(PastelCompiler compiler)
        {
            this.Constructor.ResolveTypes(compiler);
            foreach (FieldDefinition fd in this.Fields)
            {
                fd.ResolveTypes(compiler);
            }

            foreach (FunctionDefinition fd in this.Methods)
            {
                fd.ResolveTypes(compiler);
            }
        }
Example #10
0
        public void ResolveNamesAndCullUnusedCode(PastelCompiler compiler)
        {
            this.Constructor.ResolveNamesAndCullUnusedCode(compiler);
            foreach (FieldDefinition fd in this.Fields)
            {
                fd.ResolveNamesAndCullUnusedCode(compiler);
            }

            foreach (FunctionDefinition fd in this.Methods)
            {
                fd.ResolveNamesAndCullUnusedCode(compiler);
            }
        }
Example #11
0
        internal bool IsIdentical(PastelCompiler compiler, PType other)
        {
            if (!this.isTypeFinalized)
            {
                this.FinalizeType(compiler);
            }
            if (!other.isTypeFinalized)
            {
                other.FinalizeType(compiler);
            }

            if (this.Category != other.Category)
            {
                return(false);
            }

            if (this.Generics.Length != other.Generics.Length)
            {
                return(false);
            }

            if (this.IsStructOrClass)
            {
                return(this.structReference == other.structReference || this.classReference == other.classReference);
            }

            if (this.RootValue != other.RootValue)
            {
                string thisRoot = this.RootValue;
                string thatRoot = other.RootValue;
                if (thisRoot == "number" && (thatRoot == "double" || thatRoot == "int"))
                {
                    return(true);
                }
                if (thatRoot == "number" && (thisRoot == "double" || thisRoot == "int"))
                {
                    return(true);
                }
                return(false);
            }

            for (int i = this.Generics.Length - 1; i >= 0; --i)
            {
                if (!this.Generics[i].IsIdentical(compiler, other.Generics[i]))
                {
                    return(false);
                }
            }
            return(true);
        }
Example #12
0
        public void ResolveTypes(PastelCompiler compiler)
        {
            VariableScope varScope = new VariableScope(this);

            for (int i = 0; i < this.ArgTypes.Length; ++i)
            {
                varScope.DeclareVariables(this.ArgNames[i], this.ArgTypes[i]);
            }

            for (int i = 0; i < this.Code.Length; ++i)
            {
                this.Code[i].ResolveTypes(varScope, compiler);
            }
        }
Example #13
0
        private void VerifyArgTypes(PType[] expectedTypes, PastelCompiler compiler)
        {
            if (expectedTypes.Length != this.Args.Length)
            {
                throw new ParserException(this.OpenParenToken, "This function invocation has the wrong number of parameters. Expected " + expectedTypes.Length + " but found " + this.Args.Length + ".");
            }

            for (int i = 0; i < this.Args.Length; ++i)
            {
                if (!PType.CheckAssignment(compiler, expectedTypes[i], this.Args[i].ResolvedType))
                {
                    throw new ParserException(this.Args[i].FirstToken, "Wrong function arg type. Cannot convert a " + this.Args[i].ResolvedType + " to a " + expectedTypes[i]);
                }
            }
        }
Example #14
0
        internal override Expression ResolveType(VariableScope varScope, PastelCompiler compiler)
        {
            for (int i = 0; i < this.Args.Length; ++i)
            {
                this.Args[i] = this.Args[i].ResolveType(varScope, compiler);
            }

            this.Root = this.Root.ResolveType(varScope, compiler);

            if (this.Root is FunctionReference)
            {
                FunctionDefinition functionDefinition = ((FunctionReference)this.Root).Function;
                this.VerifyArgTypes(functionDefinition.ArgTypes, compiler);
                this.ResolvedType = functionDefinition.ReturnType;
                return(this);
            }
            else if (this.Root is CoreFunctionReference)
            {
                CoreFunctionReference  nfr = (CoreFunctionReference)this.Root;
                CoreFunctionInvocation nfi;
                if (nfr.Context == null)
                {
                    nfi = new CoreFunctionInvocation(this.FirstToken, nfr.CoreFunctionId, this.Args, this.Owner);
                }
                else
                {
                    nfi = new CoreFunctionInvocation(this.FirstToken, nfr.CoreFunctionId, nfr.Context, this.Args, this.Owner);
                }

                return(nfi.ResolveType(varScope, compiler));
            }
            else if (this.Root is ExtensibleFunctionReference)
            {
                return(new ExtensibleFunctionInvocation(this.FirstToken, (ExtensibleFunctionReference)this.Root, this.Args).ResolveType(varScope, compiler));
            }
            else if (this.Root is ConstructorReference)
            {
                PType typeToConstruct = ((ConstructorReference)this.Root).TypeToConstruct;
                typeToConstruct.FinalizeType(compiler);
                return(new ConstructorInvocation(this.FirstToken, typeToConstruct, this.Args, this.Owner));
            }
            else if (this.Root.ResolvedType.RootValue == "Func")
            {
                return(new FunctionPointerInvocation(compiler, this.FirstToken, this.Root, this.Args));
            }

            throw new ParserException(this.OpenParenToken, "This expression cannot be invoked like a function.");
        }
Example #15
0
        public void ResolveTypes(PastelCompiler compiler)
        {
            Dictionary <string, VariableDeclaration> globals = compiler.SharedScope == null ? compiler.Globals : compiler.SharedScope.Globals;

            VariableScope varScope = new VariableScope(this, globals);

            for (int i = 0; i < this.ArgTypes.Length; ++i)
            {
                varScope.DeclareVariables(this.ArgNames[i], this.ArgTypes[i]);
            }

            for (int i = 0; i < this.Code.Length; ++i)
            {
                this.Code[i].ResolveTypes(varScope, compiler);
            }
        }
Example #16
0
        internal void FinalizeType(PastelCompiler compilerContext)
        {
            if (this.isTypeFinalized)
            {
                return;
            }
            this.isTypeFinalized = true;

            if (this.Category == TypeCategory.STRUCT_OR_CLASS)
            {
                PastelCompiler targetContext = compilerContext;
                if (this.Namespace != null)
                {
                    if (!compilerContext.IncludedScopeNamespacesToIndex.ContainsKey(this.Namespace))
                    {
                        targetContext = null;
                    }
                    else
                    {
                        int index = compilerContext.IncludedScopeNamespacesToIndex[this.Namespace];
                        targetContext = compilerContext.IncludedScopes[index];
                    }
                }

                if (targetContext != null)
                {
                    this.structReference = targetContext.GetStructDefinition(this.TypeName);
                    this.classReference  = targetContext.GetClassDefinition(this.TypeName);
                    this.Category        = this.structReference == null ? TypeCategory.CLASS : TypeCategory.STRUCT;
                }

                if (this.structReference == null && this.classReference == null)
                {
                    throw new ParserException(this.FirstToken, "Could not find a class or struct by the name of '" + this.RootValue + "'");
                }

                if (this.structReference != null && this.classReference != null)
                {
                    throw new System.InvalidOperationException(); // this shouldn't happen. name conflicts should have been caught by now.
                }
            }

            for (int i = 0; i < this.Generics.Length; ++i)
            {
                this.Generics[i].FinalizeType(compilerContext);
            }
        }
Example #17
0
 internal override Executable ResolveWithTypeContext(PastelCompiler compiler)
 {
     this.Condition = this.Condition.ResolveWithTypeContext(compiler);
     for (int i = 0; i < this.Chunks.Length; ++i)
     {
         SwitchChunk chunk = this.Chunks[i];
         for (int j = 0; j < chunk.Cases.Length; ++j)
         {
             if (chunk.Cases[j] != null)
             {
                 chunk.Cases[j] = chunk.Cases[j].ResolveWithTypeContext(compiler);
             }
         }
         Executable.ResolveWithTypeContext(compiler, chunk.Code);
     }
     return(this);
 }
Example #18
0
        internal override Executable ResolveWithTypeContext(PastelCompiler compiler)
        {
            this.Condition = this.Condition.ResolveWithTypeContext(compiler);
            Executable.ResolveWithTypeContext(compiler, this.IfCode);
            if (this.ElseCode.Length > 0)
            {
                Executable.ResolveWithTypeContext(compiler, this.ElseCode);
            }

            if (this.Condition is InlineConstant)
            {
                bool condition = (bool)((InlineConstant)this.Condition).Value;
                return(new ExecutableBatch(this.FirstToken, condition ? this.IfCode : this.ElseCode));
            }

            return(this);
        }
Example #19
0
        internal override Executable ResolveWithTypeContext(PastelCompiler compiler)
        {
            Executable.ResolveWithTypeContext(compiler, this.InitCode);
            this.Condition = this.Condition.ResolveWithTypeContext(compiler);
            Executable.ResolveWithTypeContext(compiler, this.StepCode);
            Executable.ResolveWithTypeContext(compiler, this.Code);

            // Canonialize the for loop into a while loop.
            List <Executable> loopCode = new List <Executable>(this.Code);

            loopCode.AddRange(this.StepCode);
            WhileLoop whileLoop = new WhileLoop(this.FirstToken, this.Condition, loopCode);

            loopCode = new List <Executable>(this.InitCode);
            loopCode.Add(whileLoop);
            return(new ExecutableBatch(this.FirstToken, loopCode));
        }
Example #20
0
        public override Executable ResolveNamesAndCullUnusedCode(PastelCompiler compiler)
        {
            this.Condition = this.Condition.ResolveNamesAndCullUnusedCode(compiler);
            for (int i = 0; i < this.Chunks.Length; ++i)
            {
                SwitchChunk chunk = this.Chunks[i];
                for (int j = 0; j < chunk.Cases.Length; ++j)
                {
                    if (chunk.Cases[j] != null)
                    {
                        chunk.Cases[j] = chunk.Cases[j].ResolveNamesAndCullUnusedCode(compiler);
                    }
                }

                chunk.Code = Executable.ResolveNamesAndCullUnusedCodeForBlock(chunk.Code, compiler).ToArray();
            }
            return(this);
        }
Example #21
0
 internal override void ResolveTypes(VariableScope varScope, PastelCompiler compiler)
 {
     if (this.Expression != null)
     {
         this.Expression = this.Expression.ResolveType(varScope, compiler);
         if (!PType.CheckReturnType(varScope.RootFunctionDefinition.ReturnType, this.Expression.ResolvedType))
         {
             throw new ParserException(this.Expression.FirstToken, "This expression is not the expected return type of this function.");
         }
     }
     else
     {
         if (!this.Expression.ResolvedType.IsIdentical(PType.VOID))
         {
             throw new ParserException(this.FirstToken, "Must return a value in this function.");
         }
     }
 }
Example #22
0
        public override Expression ResolveNamesAndCullUnusedCode(PastelCompiler compiler)
        {
            string name = this.Name;

            InlineConstant constantValue = compiler.GetConstantDefinition(name);

            if (constantValue != null)
            {
                return(constantValue.CloneWithNewToken(this.FirstToken));
            }

            if (name == "Core")
            {
                return(new CoreNamespaceReference(this.FirstToken, this.Owner));
            }

            if (name == "Extension")
            {
                return(new ExtensibleNamespaceReference(this.FirstToken, this.Owner));
            }

            FunctionDefinition functionDefinition = compiler.GetFunctionDefinition(name);

            if (functionDefinition != null)
            {
                return(new FunctionReference(this.FirstToken, functionDefinition, this.Owner));
            }

            EnumDefinition enumDefinition = compiler.GetEnumDefinition(name);

            if (enumDefinition != null)
            {
                return(new EnumReference(this.FirstToken, enumDefinition, this.Owner));
            }

            if (compiler.IncludedScopeNamespacesToIndex.ContainsKey(name))
            {
                int            index           = compiler.IncludedScopeNamespacesToIndex[name];
                PastelCompiler referencedScope = compiler.IncludedScopes[index];
                return(new DependencyNamespaceReference(this.FirstToken, referencedScope, this.Owner));
            }

            return(this);
        }
Example #23
0
        internal override Expression ResolveType(VariableScope varScope, PastelCompiler compiler)
        {
            this.Root  = this.Root.ResolveType(varScope, compiler);
            this.Index = this.Index.ResolveType(varScope, compiler);

            PType rootType  = this.Root.ResolvedType;
            PType indexType = this.Index.ResolvedType;

            bool badIndex = false;

            if (rootType.RootValue == "List" || rootType.RootValue == "Array")
            {
                badIndex          = !indexType.IsIdentical(PType.INT);
                this.ResolvedType = rootType.Generics[0];
            }
            else if (rootType.RootValue == "Dictionary")
            {
                badIndex          = !indexType.IsIdentical(rootType.Generics[0]);
                this.ResolvedType = rootType.Generics[1];
            }
            else if (rootType.RootValue == "string")
            {
                badIndex          = !indexType.IsIdentical(PType.INT);
                this.ResolvedType = PType.CHAR;
                if (this.Root is InlineConstant && this.Index is InlineConstant)
                {
                    string         c        = ((string)((InlineConstant)this.Root).Value)[(int)((InlineConstant)this.Index).Value].ToString();
                    InlineConstant newValue = new InlineConstant(PType.CHAR, this.FirstToken, c);
                    newValue.ResolveType(varScope, compiler);
                    return(newValue);
                }
            }
            else
            {
                badIndex = true;
            }

            if (badIndex)
            {
                throw new ParserException(this.BracketToken, "Cannot index into a " + rootType + " with a " + indexType + ".");
            }

            return(this);
        }
Example #24
0
        public override Executable ResolveNamesAndCullUnusedCode(PastelCompiler compiler)
        {
            this.Condition = this.Condition.ResolveNamesAndCullUnusedCode(compiler);

            if (this.Condition is InlineConstant)
            {
                object value = ((InlineConstant)this.Condition).Value;
                if (value is bool)
                {
                    return(new ExecutableBatch(this.FirstToken, Executable.ResolveNamesAndCullUnusedCodeForBlock(
                                                   ((bool)value) ? this.IfCode : this.ElseCode,
                                                   compiler)));
                }
            }
            this.IfCode   = Executable.ResolveNamesAndCullUnusedCodeForBlock(this.IfCode, compiler).ToArray();
            this.ElseCode = Executable.ResolveNamesAndCullUnusedCodeForBlock(this.ElseCode, compiler).ToArray();

            return(this);
        }
Example #25
0
        internal override Expression ResolveWithTypeContext(PastelCompiler compiler)
        {
            this.Root = this.Root.ResolveWithTypeContext(compiler);

            if (this.Root is FunctionReference)
            {
                // this is okay.
            }
            else
            {
                throw new ParserException(this.OpenParenToken, "Cannot invoke this like a function.");
            }

            for (int i = 0; i < this.Args.Length; ++i)
            {
                this.Args[i] = this.Args[i].ResolveWithTypeContext(compiler);
            }
            return(this);
        }
Example #26
0
        internal override void ResolveTypes(VariableScope varScope, PastelCompiler compiler)
        {
            this.Value  = this.Value.ResolveType(varScope, compiler);
            this.Target = this.Target.ResolveType(varScope, compiler);

            if (!PType.CheckAssignment(this.Target.ResolvedType, this.Value.ResolvedType))
            {
                if (this.OpToken.Value != "=" &&
                    this.Target.ResolvedType.IsIdentical(PType.DOUBLE) &&
                    this.Value.ResolvedType.IsIdentical(PType.INT))
                {
                    // You can apply incremental ops such as += with an int to a float and that is fine without explicit conversion in any platform.
                }
                else
                {
                    throw new ParserException(this.OpToken, "Cannot assign a " + this.Value.ResolvedType + " to a " + this.Target.ResolvedType);
                }
            }
        }
Example #27
0
        internal override Executable ResolveWithTypeContext(PastelCompiler compiler)
        {
            if (this.Target is BracketIndex)
            {
                if (this.OpToken.Value != "=")
                {
                    // Java will need to be special as it will require things to be broken down into a get-then-set.
                    throw new ParserException(this.OpToken, "Incremental assignment on a key/index is not currently supported (although it really ought to be).");
                }

                BracketIndex bi       = (BracketIndex)this.Target;
                string       rootType = bi.Root.ResolvedType.RootValue;
                Expression[] args     = new Expression[] { bi.Root, bi.Index, this.Value };
                CoreFunction nf;
                if (rootType == "Array")
                {
                    nf = CoreFunction.ARRAY_SET;
                }
                else if (rootType == "List")
                {
                    nf = CoreFunction.LIST_SET;
                }
                else if (rootType == "Dictionary")
                {
                    nf = CoreFunction.DICTIONARY_SET;
                }
                else
                {
                    throw new ParserException(bi.BracketToken, "Can't use brackets here.");
                }
                return(new ExpressionAsExecutable(new CoreFunctionInvocation(
                                                      this.FirstToken,
                                                      nf,
                                                      args,
                                                      bi.Owner)).ResolveWithTypeContext(compiler));
            }

            this.Target = this.Target.ResolveWithTypeContext(compiler);
            this.Value  = this.Value.ResolveWithTypeContext(compiler);

            return(this);
        }
Example #28
0
        public override Expression ResolveNamesAndCullUnusedCode(PastelCompiler compiler)
        {
            string name = this.Name;

            InlineConstant constantValue = compiler.GetConstantDefinition(name);

            if (constantValue != null)
            {
                return(constantValue.CloneWithNewToken(this.FirstToken));
            }

            FunctionDefinition functionDefinition = compiler.GetFunctionDefinitionAndMaybeQueueForResolution(name);

            if (functionDefinition != null)
            {
                return(new FunctionReference(this.FirstToken, functionDefinition));
            }

            return(this);
        }
Example #29
0
        private bool IsParentOf(PastelCompiler compiler, PType moreSpecificTypeOrSame)
        {
            if (moreSpecificTypeOrSame == this)
            {
                return(true);
            }
            if (this.Category == TypeCategory.OBJECT)
            {
                return(true);
            }
            if (this.Generics.Length == 0)
            {
                // why no treatment of int as a subtype of double? because there needs to be an explicit type conversion
                // for languages that aren't strongly typed and won't auto-convert.
                return(this.RootValue == moreSpecificTypeOrSame.RootValue);
            }

            // All that's left are Arrays, Lists, and Dictionaries, which must match exactly.
            return(this.IsIdentical(compiler, moreSpecificTypeOrSame));
        }
Example #30
0
        internal bool IsIdenticalOrChildOf(PastelCompiler compiler, PType other)
        {
            if (this.IsIdentical(compiler, other))
            {
                return(true);
            }

            // only structs or classes should be here if this is to return true. If not, then it's a no.
            if (!this.IsStructOrClass || !other.IsStructOrClass)
            {
                return(false);
            }

            if (this.IsStruct != other.IsStruct)
            {
                return(false);
            }
            if (this.IsStruct)
            {
                if (this.StructDef == null || other.StructDef == null)
                {
                    throw new System.Exception("This check cannot occur without resolving struct information for PTypes.");
                }
                StructDefinition walker = this.StructDef;
                StructDefinition target = other.StructDef;
                while (walker != null)
                {
                    if (walker == target)
                    {
                        return(true);
                    }
                    walker = walker.Parent;
                }
            }
            if (this.IsClass)
            {
                throw new System.NotImplementedException();
            }

            return(false);
        }