Beispiel #1
0
 public FunctionDefinition(string name, Span span, string documentation, ConstDefinition signature, StructDefinition argumentStruct, StructDefinition returnStruct, Definition?parent = null)
     : base(name, span, documentation, parent)
 {
     Signature      = signature;
     ArgumentStruct = argumentStruct;
     ReturnStruct   = returnStruct;
 }
Beispiel #2
0
        public ConstDefinition[] SortConstants()
        {
            for (int i = 0; i < this.consts.Length; ++i)
            {
                ConstDefinition cnst = this.consts[i];
                if (!this.resolved.Contains(cnst))
                {
                    this.ResolveConstDependency(cnst);
                }
            }

            ConstDefinition[] output = this.output.ToArray();
            this.output.Clear();
            this.resolving.Clear();
            this.resolved.Clear();
            return(output);
        }
        private ConstDefinition ParseConstDefinition()
        {
            var id = ParseIdentifier();

            var node = new ConstDefinition();

            node.AddChild(id);

            var t = NextToken();

            AssertOperator(Operator.Equal, t);

            var expr = ParseExpression();

            node.AddChild(expr);

            return(node);
        }
Beispiel #4
0
        protected override ConstDefinition ParseConst(
            TokenStream tokens,
            Node owner,
            FileScope fileScope,
            ModifierCollection modifiers,
            AnnotationCollection annotations)
        {
            Token           constToken     = tokens.PopExpected(this.parser.Keywords.CONST);
            Token           nameToken      = tokens.Pop();
            ConstDefinition constStatement = new ConstDefinition(constToken, AType.Any(constToken), nameToken, owner, fileScope, modifiers, annotations);

            this.parser.VerifyIdentifier(nameToken);
            tokens.PopExpected("=");
            constStatement.Expression = this.parser.ExpressionParser.Parse(tokens, constStatement);
            tokens.PopExpected(";");

            return(constStatement);
        }
        private static TopLevelEntity ParseConstDefinition(
            ParserContext context,
            TopLevelEntity parent,
            Token firstToken,
            Dictionary <string, Token> modifiers,
            TokenStream tokens)
        {
            Token      constToken = tokens.PopExpected("const");
            CSharpType constType  = CSharpType.Parse(tokens);
            Token      name       = tokens.PopWord();

            tokens.PopExpected("=");
            ConstDefinition constDef = new ConstDefinition(firstToken, modifiers, constType, name, parent);
            Expression      value    = ExpressionParser.Parse(context, tokens, constDef);

            tokens.PopExpected(";");
            constDef.Value = value;
            return(constDef);
        }
Beispiel #6
0
        private void ResolveConstDependency(ConstDefinition cnst)
        {
            if (this.resolving.Contains(cnst))
            {
                throw new ParserException(cnst, "This constant has a dependency loop.");
            }

            this.resolving.Add(cnst);

            foreach (ConstReference cnstRef in cnst.Expression.GetFlattenedDescendants().OfType <ConstReference>())
            {
                if (cnstRef.CompilationScope == this.currentScope)
                {
                    this.ResolveConstDependency(cnstRef.ConstStatement);
                }
            }

            this.resolving.Remove(cnst);
            this.resolved.Add(cnst);
            this.output.Add(cnst);
        }
Beispiel #7
0
        // Generally this is used with the name resolver. So for example, you have a refernce to a ClassDefinition
        // instance from the resolver, but you want to turn it into a ClassReference instance.
        // TODO: put this in a method on these classes and implement an interface. The function signatures are all close enough.
        public static Expression ConvertStaticReferenceToExpression(TopLevelEntity item, Token primaryToken, Node owner)
        {
            Expression     output           = null;
            TopLevelEntity referencedEntity = null;

            if (item is ClassDefinition)
            {
                ClassDefinition classDef = (ClassDefinition)item;
                output           = new ClassReference(primaryToken, classDef, owner);
                referencedEntity = classDef;
            }
            else if (item is EnumDefinition)
            {
                EnumDefinition enumDef = (EnumDefinition)item;
                output           = new EnumReference(primaryToken, enumDef, owner);
                referencedEntity = enumDef;
            }
            else if (item is ConstDefinition)
            {
                ConstDefinition constDef = (ConstDefinition)item;
                output           = new ConstReference(primaryToken, constDef, owner);
                referencedEntity = constDef;
            }
            else if (item is FunctionDefinition)
            {
                FunctionDefinition funcDef = (FunctionDefinition)item;
                output           = new FunctionReference(primaryToken, funcDef, owner);
                referencedEntity = funcDef;
            }
            else
            {
                throw new InvalidOperationException();
            }

            Node.EnsureAccessIsAllowed(primaryToken, owner, referencedEntity);

            return(output);
        }
Beispiel #8
0
 public DuplicateConstDefinitionException(ConstDefinition definition)
     : base($"An illegal redefinition for the constant '{definition.Name}' was found in '{Path.GetFileName(definition.Span.FileName)}'", definition.Span, 122)
 {
 }
Beispiel #9
0
 private void WriteConstDefinition(IndentedStringBuilder builder, ConstDefinition d)
 {
     builder.AppendLine(
         $"pub const {MakeConstIdent(d.Name)}: {TypeName(d.Value.Type, OwnershipType.Constant)} = {EmitLiteral(d.Value)};");
 }
Beispiel #10
0
        private static ConstDefinition CreateConstDefinition(ref Lexem lex)
        {
            DataType constType = DataType.Undefined;
            switch (lex.Type)
            {
                case LexemType.BooleanLiteral:
                    constType = DataType.Boolean;
                    break;
                case LexemType.DateLiteral:
                    constType = DataType.Date;
                    break;
                case LexemType.NumberLiteral:
                    constType = DataType.Number;
                    break;
                case LexemType.StringLiteral:
                    constType = DataType.String;
                    break;
                case LexemType.NullLiteral:
                    constType = DataType.GenericValue;
                    break;
            }

            ConstDefinition cDef = new ConstDefinition()
            {
                Type = constType,
                Presentation = lex.Content
            };
            return cDef;
        }
Beispiel #11
0
        private void BuildContinuationInternal(bool interruptOnCall, out string lastIdentifier)
        {
            lastIdentifier = null;
            while (true)
            {
                if (_lastExtractedLexem.Token == Token.Dot)
                {
                    NextToken();
                    if (!LanguageDef.IsIdentifier(ref _lastExtractedLexem))
                        throw CompilerException.IdentifierExpected();

                    string identifier = _lastExtractedLexem.Content;
                    NextToken();
                    if (_lastExtractedLexem.Token == Token.OpenPar)
                    {
                        if (interruptOnCall)
                        {
                            lastIdentifier = identifier;
                            return;
                        }
                        else
                        {
                            var args = BuildArgumentList();
                            var cDef = new ConstDefinition();
                            cDef.Type = DataType.String;
                            cDef.Presentation = identifier;
                            int lastIdentifierConst = GetConstNumber(ref cDef);
                            AddCommand(OperationCode.ArgNum, args.Length);
                            AddCommand(OperationCode.ResolveMethodFunc, lastIdentifierConst);
                        }
                    }
                    else
                    {
                        ResolveProperty(identifier);
                    }
                }
                else if (_lastExtractedLexem.Token == Token.OpenBracket)
                {
                    NextToken();
                    if (_lastExtractedLexem.Token == Token.CloseBracket)
                        throw CompilerException.ExpressionExpected();

                    BuildExpression(Token.CloseBracket);
                    System.Diagnostics.Debug.Assert(_lastExtractedLexem.Token == Token.CloseBracket);
                    NextToken();

                    AddCommand(OperationCode.PushIndexed, 0);
                }
                else
                {
                    break;
                }
            }
        }
Beispiel #12
0
        private void BuildAccessChainLeftHand()
        {
            string ident;
            BuildContinuationLeftHand(out ident);

            if (ident == null)
            {
                // это присваивание
                if (_lastExtractedLexem.Token != Token.Equal)
                    throw CompilerException.UnexpectedOperation();

                NextToken(); // перешли к выражению
                BuildExpression(Token.Semicolon);
                AddCommand(OperationCode.AssignRef, 0);

            }
            else
            {
                // это вызов
                System.Diagnostics.Debug.Assert(_lastExtractedLexem.Token == Token.OpenPar);
                var args = PushMethodArgumentsBeforeCall();
                var cDef = new ConstDefinition();
                cDef.Type = DataType.String;
                cDef.Presentation = ident;
                int lastIdentifierConst = GetConstNumber(ref cDef);

                if (_lastExtractedLexem.Token == Token.Dot || _lastExtractedLexem.Token == Token.OpenBracket)
                {
                    AddCommand(OperationCode.ResolveMethodFunc, lastIdentifierConst);
                    BuildAccessChainLeftHand();
                }
                else
                {
                    AddCommand(OperationCode.ResolveMethodProc, lastIdentifierConst);
                }

            }
        }
Beispiel #13
0
 private void ResolveProperty(string identifier)
 {
     var cDef = new ConstDefinition();
     cDef.Type = DataType.String;
     cDef.Presentation = identifier;
     var identifierConstIndex = GetConstNumber(ref cDef);
     AddCommand(OperationCode.ResolveProp, identifierConstIndex);
 }
Beispiel #14
0
        private void NewObjectStaticConstructor()
        {
            var name = _lastExtractedLexem.Content;
            var cDef = new ConstDefinition()
            {
                Type = DataType.String,
                Presentation = name
            };

            AddCommand(OperationCode.PushConst, GetConstNumber(ref cDef));

            NextToken();
            bool[] argsPassed;
            if (_lastExtractedLexem.Token == Token.OpenPar)
            {
                // Отрабатываем только в тех случаях, если явно указана скобка.
                // В остальных случаях дальнейшую обработку отдаём наружу
                argsPassed = BuildArgumentList();
            }
            else
            {
                argsPassed = new bool[0];
                // TODO: разобраться с костылем про BackOneToken()
                //if (_lastExtractedLexem.Token == Token.ClosePar)
                    //BackOneToken();
            }

            AddCommand(OperationCode.NewInstance, argsPassed.Length);
        }
Beispiel #15
0
 private int GetConstNumber(ref ConstDefinition cDef)
 {
     var idx = _module.Constants.IndexOf(cDef);
     if (idx < 0)
     {
         idx = _module.Constants.Count;
         _module.Constants.Add(cDef);
     }
     return idx;
 }
Beispiel #16
0
        private void DispatchMethodBody()
        {
            _inMethodScope = true;
            BuildVariableDefinitions();
            _isStatementsDefined = true;
            BuildCodeBatch();
            if (_isFunctionProcessed)
            {
                var undefConst = new ConstDefinition()
                {
                    Type = DataType.Undefined,
                    Presentation = "Неопределено"
                };

                AddCommand(OperationCode.PushConst, GetConstNumber(ref undefConst));

            }
            AddCommand(OperationCode.Return, 0);
            _isStatementsDefined = false;
            _inMethodScope = false;
        }