Пример #1
0
        protected override void VisitTypeSyntax(TypeSyntax pNode)
        {
            //TODO i need to have <T> after methods so we can define our generic types and propagate them
            foreach (var a in pNode.GenericArguments)
            {
                Visit(a);
            }

            var result = _unit.FromString(pNode, out SmallType type);

            switch (result)
            {
            //case Compiler.FindResult.NotFound:
            //    CompilerErrors.UndeclaredType(name, pNode.Span);
            //    break;

            case Compiler.FindResult.IncorrectScope:
                CompilerErrors.TypeNotInScope(SyntaxHelper.GetFullTypeName(pNode), pNode.Span);
                break;
            }

            if (type.IsGenericType)
            {
                type = _unit.MakeConcreteType(type, SyntaxHelper.SelectNodeTypes(pNode.GenericArguments));
            }
            pNode.SetType(type);

            if (pNode.Namespace != null && !_unit.HasReference(pNode.Namespace.Value))
            {
                CompilerErrors.NamespaceNotDefined(pNode.Namespace, pNode.Span);
            }
        }
Пример #2
0
        protected override void VisitAssignmentSyntax(AssignmentSyntax pNode)
        {
            base.VisitAssignmentSyntax(pNode);
            if (pNode.Value.Type == SmallTypeCache.NoValue)
            {
                CompilerErrors.ExpressionNoValue(pNode.Value.Span);
            }

            var isTuple = pNode.Value.Type.IsTuple;

            for (int i = 0; i < pNode.Variables.Count; i++)
            {
                //Check if we are assigning to a const variable
                if (_locals.TryGetVariable(pNode.Variables[i].Value, out LocalDefinition ld) && ld.IsConst)
                {
                    CompilerErrors.CannotAssignCost(pNode.Variables[i], pNode.Variables[i].Span);
                }

                var t = isTuple ? pNode.Value.Type.GetFieldType(i) : pNode.Value.Type;

                //We have to set the type of discards so the tuple is created properly
                if (SyntaxHelper.IsDiscard(pNode.Variables[i]))
                {
                    ((DiscardSyntax)pNode.Variables[i]).SetType(t);
                }
            }
        }
Пример #3
0
        protected override SyntaxNode VisitBlockSyntax(BlockSyntax pNode)
        {
            //Rewrite any statements after the return statement to be a NOP
            List <SyntaxNode> statements = new List <SyntaxNode>(pNode.Statements.Count);
            bool returnFound             = false;

            for (int i = 0; i < pNode.Statements.Count; i++)
            {
                if (!returnFound)
                {
                    statements.Add(Visit(pNode.Statements[i]));
                }
                else
                {
                    CompilerErrors.UnreachableCode(pNode.Statements[i].Span);
                }

                if (pNode.Statements[i].SyntaxType == SyntaxType.Return)
                {
                    returnFound = true;
                }
            }

            return(SyntaxFactory.Block(statements));
        }
        protected override void VisitIdentifierSyntax(IdentifierSyntax pNode)
        {
            _locals.SetValue(pNode.Value, new LocalReference(pNode.Span, pNode.Value, true));
            var currentStruct = Struct;
            var currentType   = CurrentType;

            if (currentType != null)
            {
                var definition = currentType.GetField(pNode.Value);

                //Only the defining struct can access hidden fields
                if (definition.Visibility == FieldVisibility.Hidden && currentStruct != currentType)
                {
                    //Check if the struct is a trait that implements the current type
                    //This will allow implementing traits to access the struct's private fields
                    if (currentStruct == null || !currentStruct.IsTrait || !currentType.IsAssignableFrom(currentStruct))
                    {
                        CompilerErrors.AccessPrivateMember(pNode, pNode.Span);
                    }
                }
            }

            if (currentStruct != null &&
                Store.GetValueOrDefault <bool>("InConstructor") &&
                Store.GetValueOrDefault <bool>("InAssignment"))
            {
                _usedFields.Add(pNode.Value);
            }
            base.VisitIdentifierSyntax(pNode);
        }
Пример #5
0
        private void TryPolyStruct(TypeDefinitionSyntax pNode, StructInitializerSyntax pInitializer)
        {
            //Number of generic type parameters on the type does not match
            //the number of type arguments specified at the initialization site
            if (pInitializer.Struct.GenericArguments.Count != pNode.TypeParameters.Count)
            {
                CompilerErrors.TypePolyArgumentCount(pInitializer.Struct, pNode.TypeParameters.Count, pInitializer.Span);
            }

            //We just create a dictionary of T,int; T2,string; etc... and feed that to the type
            //When the type is emitted it will create a copy of itself for each unique generic argument
            Dictionary <string, SmallType> types = new Dictionary <string, SmallType>();

            for (int i = 0; i < pNode.TypeParameters.Count; i++)
            {
                types.Add(pNode.TypeParameters[i], pInitializer.Struct.GenericArguments[i].Type);
            }
            pNode.AddTypeMapping(types);

            //We also need to add the same type mappings for any trait implementations
            var name = SyntaxHelper.GetFullTypeName(pNode.GetApplicableType());

            if (_implements.ContainsKey(name))
            {
                foreach (var impl in _implements[name])
                {
                    impl.AddTypeMapping(types);
                }
            }
        }
Пример #6
0
        protected override void VisitStructInitializerSyntax(StructInitializerSyntax pNode)
        {
            //Check if the type exists
            if (pNode.Struct.Type == SmallTypeCache.Undefined)
            {
                CompilerErrors.UndeclaredType(pNode.Struct.ToString(), pNode.Span);
            }
            //Check if the type is a trait
            else if (pNode.Struct.Type.IsTrait)
            {
                CompilerErrors.AttemptDeclareTrait(pNode.Struct.Type, pNode.Span);
            }
            //Ensure the constructor arguments
            else if (pNode.Struct.Type.HasDefinedConstructor())
            {
                var m = pNode.Struct.Type.GetConstructor();
                for (int i = 0; i < m.ArgumentTypes.Count; i++)
                {
                    if (!CanCast(pNode.Arguments[i].Type, m.ArgumentTypes[i]))
                    {
                        CompilerErrors.TypeCastError(pNode.Arguments[i].Type, m.ArgumentTypes[i], pNode.Arguments[i].Span);
                    }
                }
            }

            base.VisitStructInitializerSyntax(pNode);
        }
Пример #7
0
        protected override void VisitUnaryExpressionSyntax(UnaryExpressionSyntax pNode)
        {
            switch (pNode.Operator)
            {
            case UnaryExpressionOperator.Not:
                if (!CanCast(pNode.Value.Type, SmallTypeCache.Boolean))
                {
                    CompilerErrors.TypeCastError(pNode.Value.Type, SmallTypeCache.Boolean, pNode.Value.Span);
                }
                break;

            case UnaryExpressionOperator.Length:
                if (!pNode.Value.Type.IsArray)
                {
                    CompilerErrors.TypeCastError(pNode.Value.Type.ToString(), "array", pNode.Span);
                }
                break;

            case UnaryExpressionOperator.PreDecrement:
            case UnaryExpressionOperator.PreIncrement:
            case UnaryExpressionOperator.PostDecrement:
            case UnaryExpressionOperator.PostIncrement:
            case UnaryExpressionOperator.Negative:
                if (!TypeHelper.IsInt(pNode.Value.Type))
                {
                    CompilerErrors.TypeCastError(pNode.Value.Type, SmallTypeCache.Int, pNode.Span);
                }
                break;
            }
            base.VisitUnaryExpressionSyntax(pNode);
        }
Пример #8
0
        private Token NextSymbol()
        {
            //We have to watch for whitespace before and after comments
            //Otherwise we could begin parsing a token starting with whitespace
            SkipWhitespace();
            SkipComments();
            SkipWhitespace();

            if (_tokenizer.EOF)
            {
                return(new Token(TokenType.EndOfFile, 3));
            }

            _length = 0;
            _tokenizer.StartToken();

            //Identifiers
            if (char.IsLetter(_tokenizer.Current) || _tokenizer.Current == '_')
            {
                return(CreateIdentifier());
            }

            //Numbers
            if (char.IsDigit(_tokenizer.Current))
            {
                return(CreateNumber());
            }

            //Strings
            if (_tokenizer.Current == '"')
            {
                return(CreateString());
            }

            //Annotation
            if (_tokenizer.Current == '@')
            {
                return(CreateAnnotation());
            }

            //Symbols and keywords
            TrieNode t      = _keywords.Root;
            TrieNode result = t;

            while ((t = t.FindChild(_tokenizer.Current)) != null)
            {
                result = t;
                Eat();
            }
            if (!result.Leaf)
            {
                var span = new TextSpan(_tokenizer.Index, _tokenizer.Index + 1, _tokenizer.Line, _tokenizer.Column, Source, SourcePath);
                CompilerErrors.UnknownCharacter(_tokenizer.Current, span);
                Eat();
                return(CreateToken(TokenType.Unknown));
            }

            return(CreateToken(result.Type));
        }
Пример #9
0
 protected override void VisitTypedIdentifierSyntax(TypedIdentifierSyntax pNode)
 {
     if (pNode.Type == SmallTypeCache.Undefined)
     {
         CompilerErrors.UndeclaredType(pNode.TypeNode.Value, pNode.Span);
     }
     base.VisitTypedIdentifierSyntax(pNode);
 }
Пример #10
0
 protected override void VisitWhileSyntax(WhileSyntax pNode)
 {
     if (!CanCast(pNode.Condition.Type, SmallTypeCache.Boolean))
     {
         CompilerErrors.TypeCastError(pNode.Condition.Type, SmallTypeCache.Boolean, pNode.Condition.Span);
     }
     base.VisitWhileSyntax(pNode);
 }
Пример #11
0
 protected override void VisitDeclarationSyntax(DeclarationSyntax pNode)
 {
     if (pNode.IsConst && !IsConstant(null, pNode.Value))
     {
         CompilerErrors.ConstantNotConstantValue(pNode.Value.Span);
     }
     base.VisitDeclarationSyntax(pNode);
 }
Пример #12
0
 protected override void VisitTypeDefinitionSyntax(TypeDefinitionSyntax pNode)
 {
     if (pNode.DefinitionType != DefinitionTypes.Implement && pNode.DeclaredType.Namespace != null)
     {
         CompilerErrors.StructNamespace(pNode.Span);
     }
     base.VisitTypeDefinitionSyntax(pNode);
 }
Пример #13
0
 protected override void VisitArrayLiteralSyntax(ArrayLiteralSyntax pNode)
 {
     if (pNode.Type == SmallTypeCache.Undefined)
     {
         CompilerErrors.UndeclaredType(pNode.TypeNode.Value, pNode.Span);
     }
     base.VisitArrayLiteralSyntax(pNode);
 }
Пример #14
0
        public virtual void WriteCompileError(string traceMsg)
        {
            string objectName = GetType().Name;

            traceMsg = string.Format(traceMsg, objectName, string.IsNullOrEmpty(Name) ? objectName : Name);
            CompilerErrors.Add(traceMsg);

            WriteOutput(traceMsg);
        }
Пример #15
0
        private bool AddMethodToCache(SmallType pType, MethodSyntax pMethod, out MethodDefinition pDefinition)
        {
            //Check for duplicate method definitions
            Compiler.FindResult found;
            if (pMethod.SyntaxType == SyntaxType.Method)
            {
                found = _unit.MethodExists(pType, pMethod);
            }
            else if (pMethod.SyntaxType == SyntaxType.CastDefinition)
            {
                found = _unit.CastExists(pType, pMethod.Type, out MethodDefinition pDef);
            }
            else
            {
                throw new InvalidOperationException("Unknown method type " + pMethod.SyntaxType.ToString());
            }

            if (found != Compiler.FindResult.NotFound)
            {
                if (pMethod.SyntaxType == SyntaxType.Method)
                {
                    CompilerErrors.MethodDuplicate(pMethod, pMethod.Span);
                }
                else if (pMethod.SyntaxType == SyntaxType.CastDefinition)
                {
                    CompilerErrors.CastDuplicate(pMethod.Parameters[0].Type, pMethod.Type, pMethod.Span);
                }
                pDefinition = default;
                return(false);
            }
            else
            {
                //Create the tuple type if we are returning more than one value from a method
                //This will cache it in our SmallTypeCache so it can be found later
                if (pMethod.ReturnValues.Count > 1)
                {
                    SmallTypeCache.GetOrCreateTuple(SyntaxHelper.SelectNodeTypes(pMethod.ReturnValues));
                }

                //Set method and return types
                foreach (var p in pMethod.Parameters)
                {
                    _unit.FromString(p.TypeNode, out SmallType t);
                    p.TypeNode.SetType(t);
                }
                foreach (var r in pMethod.ReturnValues)
                {
                    _unit.FromString(r, out SmallType t);
                    r.SetType(t);
                }

                //Add method
                pDefinition = _unit.AddMethod(pType, pMethod);
                return(true);
            }
        }
Пример #16
0
 protected override void VisitReturnSyntax(ReturnSyntax pNode)
 {
     for (int i = 0; i < Math.Min(_methodReturns.Length, pNode.Values.Count); i++)
     {
         if (!CanCast(pNode.Values[i].Type, _methodReturns[i]))
         {
             CompilerErrors.TypeCastError(pNode.Values[i].Type, _methodReturns[i], pNode.Values[i].Span);
         }
     }
     base.VisitReturnSyntax(pNode);
 }
Пример #17
0
        public override bool Compile()
        {
            base.Compile();

            Actions.ForEach(c =>
            {
                c.Compile();
                c.CompilerErrors.ToList().ForEach(d => CompilerErrors.Add(d));
            });

            return(IsCompiled);
        }
Пример #18
0
 protected override void VisitMethodSyntax(MethodSyntax pNode)
 {
     for (int i = 0; i < pNode.ReturnValues.Count; i++)
     {
         if (pNode.ReturnValues[i].Type == SmallTypeCache.Undefined)
         {
             CompilerErrors.UndeclaredType(pNode.ReturnValues[i].Value, pNode.ReturnValues[i].Span);
         }
     }
     _methodReturns = SyntaxHelper.SelectNodeTypes(pNode.ReturnValues);
     base.VisitMethodSyntax(pNode);
 }
Пример #19
0
 protected override void VisitTernaryExpression(TernaryExpressionSyntax pNode)
 {
     if (!CanCast(pNode.Condition.Type, SmallTypeCache.Boolean))
     {
         CompilerErrors.TypeCastError(pNode.Condition.Type, SmallTypeCache.Boolean, pNode.Condition.Span);
     }
     if (pNode.Left.Type != pNode.Right.Type)
     {
         CompilerErrors.TypeCastError(pNode.Left.Type, pNode.Right.Type, pNode.Span);
     }
     base.VisitTernaryExpression(pNode);
 }
Пример #20
0
        protected override void VisitBinaryExpressionSyntax(BinaryExpressionSyntax pNode)
        {
            switch (pNode.Operator)
            {
            case BinaryExpressionOperator.And:
            case BinaryExpressionOperator.Or:
                if (!CanCast(pNode.Left.Type, SmallTypeCache.Boolean))
                {
                    CompilerErrors.TypeCastError(pNode.Left.Type, SmallTypeCache.Boolean, pNode.Span);
                }
                if (!CanCast(pNode.Right.Type, SmallTypeCache.Boolean))
                {
                    CompilerErrors.TypeCastError(pNode.Right.Type, SmallTypeCache.Boolean, pNode.Span);
                }
                break;

            case BinaryExpressionOperator.BitwiseAnd:
            case BinaryExpressionOperator.BitwiseOr:
                if (!CanCast(pNode.Left.Type, SmallTypeCache.Int))
                {
                    CompilerErrors.TypeCastError(pNode.Left.Type, SmallTypeCache.Int, pNode.Span);
                }
                if (!CanCast(pNode.Right.Type, SmallTypeCache.Int))
                {
                    CompilerErrors.TypeCastError(pNode.Right.Type, SmallTypeCache.Int, pNode.Span);
                }
                break;

            case BinaryExpressionOperator.LeftBitShift:
            case BinaryExpressionOperator.RightBitShift:
                if (pNode.Left.Type != SmallTypeCache.Undefined &&
                    pNode.Right.Type != SmallTypeCache.Undefined &&
                    !CanCast(pNode.Left.Type, pNode.Right.Type))
                {
                    CompilerErrors.TypeCastError(pNode.Left.Type, pNode.Right.Type, pNode.Span);
                }
                break;

            default:
                //Types can be undefined if the type was not found.
                //These errors will be reported when the type is first found
                if (pNode.Left.Type != SmallTypeCache.Undefined &&
                    pNode.Right.Type != SmallTypeCache.Undefined &&
                    BinaryExpressionSyntax.GetResultType(pNode.Left.Type, pNode.Operator, pNode.Right.Type) == SmallTypeCache.Undefined)
                {
                    CompilerErrors.TypeCastError(pNode.Left.Type, pNode.Right.Type, pNode.Span);
                }
                break;
            }

            base.VisitBinaryExpressionSyntax(pNode);
        }
Пример #21
0
        protected override void VisitCaseSyntax(CaseSyntax pNode)
        {
            var caseType = Store.GetValue <SmallType>("CaseType");

            foreach (var c in pNode.Conditions)
            {
                if (!CanCast(caseType, c.Type))
                {
                    CompilerErrors.TypeCastError(c.Type, caseType, pNode.Span);
                }
            }
            base.VisitCaseSyntax(pNode);
        }
Пример #22
0
        protected override void VisitTypedIdentifierSyntax(TypedIdentifierSyntax pNode)
        {
            base.VisitTypedIdentifierSyntax(pNode);

            if (_locals.IsVariableDefinedInScope(pNode.Value))
            {
                CompilerErrors.IdentifierAlreadyDeclared(pNode, pNode.Span);
            }
            else
            {
                _locals.DefineVariableInScope(pNode.Value, LocalDefinition.Create(false, pNode.Type));
            }
        }
Пример #23
0
 public override void SyntaxError(
     IRecognizer recognizer,
     IToken offendingSymbol,
     int line,
     int charPositionInLine,
     string msg,
     RecognitionException e)
 {
     CompilerErrors.Add(
         new CompilerError {
         Column = charPositionInLine, Line = line, Message = msg, Exception = e
     });
     Console.WriteLine($"[{line}/{charPositionInLine}] - {msg}");
 }
Пример #24
0
        protected override void VisitArrayAccessSyntax(ArrayAccessSyntax pNode)
        {
            if (!CanCast(pNode.Index.Type, SmallTypeCache.Int))
            {
                CompilerErrors.TypeCastError(pNode.Index.Type, SmallTypeCache.Int, pNode.Index.Span);
            }

            if (!pNode.Identifier.Type.IsArray)
            {
                CompilerErrors.CannotIndex(pNode.Identifier.Type, pNode.Span);
            }

            base.VisitArrayAccessSyntax(pNode);
        }
 protected override void VisitBreakSyntax(BreakSyntax pNode)
 {
     if (!Store.GetValueOrDefault <bool>("CanBreak"))
     {
         CompilerErrors.InvalidBreakLocation(pNode.Span);
     }
     else
     {
         if (pNode.CountAsInt >= _breakCount)
         {
             CompilerErrors.InvalidBreakCount(_breakCount - 1, pNode.Span);
         }
     }
 }
Пример #26
0
        protected override void VisitIdentifierSyntax(IdentifierSyntax pNode)
        {
            if (CurrentType != null || !_unit.IsTypeDefined(Namespace, pNode.Value))
            {
                //Normal identifier, continue as usual
                if (!IsVariableDefined(pNode.Value, out SmallType type))
                {
                    if (CurrentType == null)
                    {
                        //Generate a slightly different error message if we are in a struct
                        //This can happen if we forget self
                        if (Struct != null)
                        {
                            CompilerErrors.IdentifierNotDeclaredSelf(pNode, pNode.Span);
                        }
                        else
                        {
                            CompilerErrors.IdentifierNotDeclared(pNode, pNode.Span);
                        }
                    }
                    else
                    {
                        CompilerErrors.IdentifierNotDeclared(CurrentType, pNode, pNode.Span);
                    }
                }
                else
                {
                    pNode.SetType(type);
                }
            }
            else
            {
                //Shared or enum value
                var result = _unit.FromString(Namespace, pNode.Value, out SmallType t);
                switch (result)
                {
                case Compiler.FindResult.Found:
                    pNode.SetType(t);
                    break;

                case Compiler.FindResult.IncorrectScope:
                    CompilerErrors.TypeNotInScope(pNode.Value, pNode.Span);
                    break;

                case Compiler.FindResult.NotFound:
                    CompilerErrors.UndeclaredType(pNode.Value, pNode.Span);
                    break;
                }
            }
        }
        protected override void VisitModuleSyntax(ModuleSyntax pNode)
        {
            _locals = new ScopeCache <LocalReference>();
            _locals.AddScope();
            using (var v = Store.AddValue <string>("RunMethod", null))
            {
                base.VisitModuleSyntax(pNode);

                if (pNode == _mainModule && v.Value == null)
                {
                    CompilerErrors.NoRunMethod(pNode.Span);
                }
            }
            _locals.RemoveScope();
        }
Пример #28
0
        protected override void VisitAssignmentSyntax(AssignmentSyntax pNode)
        {
            var isTuple = pNode.Value.Type.IsTuple;

            for (int i = 0; i < pNode.Variables.Count; i++)
            {
                var valueType = isTuple ? pNode.Value.Type.GetFieldType(i) : pNode.Value.Type;

                if (!CanCast(pNode.Variables[i].Type, valueType))
                {
                    CompilerErrors.TypeCastError(pNode.Variables[i].Type, valueType, pNode.Span);
                }
            }
            base.VisitAssignmentSyntax(pNode);
        }
Пример #29
0
        public override bool Compile()
        {
            base.Compile();

            foreach (ServiceActionInput sai in ServiceActionInputs)
            {
                sai.Compile();
                sai.CompilerErrors.ToList().ForEach(c => CompilerErrors.Add(c));
            }

            if (CompilerErrors.Count > 0)
            {
                return(IsCompiled);
            }

            switch (ActionType)
            {
            case enActionType.InvokeDynamicService:
                if (string.IsNullOrEmpty(ServiceName))
                {
                    WriteCompileError(Resources.CompilerError_MissingServiceName);
                }
                break;

            case enActionType.Workflow:
                break;

            default:
                //A Source Name is required except in the case of Management Dynamic Services
                if (string.IsNullOrEmpty(SourceName) && ActionType != enActionType.InvokeManagementDynamicService)
                {
                    WriteCompileError(Resources.CompilerError_MissingSourceName);
                }
                if (string.IsNullOrEmpty(SourceMethod))
                {
                    WriteCompileError(Resources.CompilerError_MissingSourceMethod);
                }
                //A source is required except in the case of Management Dynamic Services
                if (Source == null && ActionType != enActionType.InvokeManagementDynamicService)
                {
                    WriteCompileError(Resources.CompilerError_SourceNotFound);
                }
                break;
            }

            return(IsCompiled);
        }
Пример #30
0
        protected override void VisitDeclarationSyntax(DeclarationSyntax pNode)
        {
            Visit(pNode.Value);

            var isTuple = pNode.Value.Type.IsTuple;

            for (int i = 0; i < pNode.Variables.Count; i++)
            {
                if (!SyntaxHelper.IsDiscard(pNode.Variables[i]))
                {
                    if (_locals.IsVariableDefinedInScope(pNode.Variables[i].Value))
                    {
                        CompilerErrors.IdentifierAlreadyDeclared(pNode.Variables[i], pNode.Span);
                    }
                    else
                    {
                        //We do not allow variables to have the same names as types
                        //This makes it easier to check for "static" method/fields
                        if (SmallTypeCache.IsTypeDefined(pNode.Variables[i].Value))
                        {
                            CompilerErrors.ValueDefinedAsType(pNode.Variables[i], pNode.Variables[i].Span);
                        }
                        else
                        {
                            //For tuple types we set the individual variables to the tuple field type... not the tuple itself
                            var t = isTuple ? pNode.Value.Type.GetFieldType(i) : pNode.Value.Type;

                            //Report expression errors and change the type to Undefined so we don't get further no expression errors
                            if (pNode.Value.Type == SmallTypeCache.NoValue)
                            {
                                CompilerErrors.ExpressionNoValue(pNode.Value.Span);
                                t = SmallTypeCache.Undefined;
                            }

                            pNode.Variables[i].SetType(t);
                            _locals.DefineVariableInScope(pNode.Variables[i].Value, LocalDefinition.Create(pNode.IsConst, pNode.Variables[i].Type));
                        }
                    }
                }
            }

            //Check that we are declaring the proper number of variables
            if (isTuple && pNode.Value.Type.GetFieldCount() != pNode.Variables.Count)
            {
                CompilerErrors.DeclarationCountMismatch(pNode.Value.Type.GetFieldCount(), pNode.Variables.Count, pNode.Span);
            }
        }