Beispiel #1
0
        public static object?EvalExpression(DogeNode expression, Dictionary <string, object?> locals)
        {
            switch (expression)
            {
            case DogeBinaryExpression binaryExpression:
                var            lhs = EvalExpression(binaryExpression.LeftHandSide, locals);
                Func <object?> rhs = () => EvalExpression(binaryExpression.RightHandSide, locals);

                switch (binaryExpression.BinaryOperator)
                {
                case DogeBinaryOperator.Add:
                    return(lhs switch
                    {
                        double d => (object)(d + (double)rhs() !),
                        float d => d + (float)rhs() !,
                        long d => d + (long)rhs() !,
                        int d => d + (int)rhs() !,
                        short d => d + (short)rhs() !,
                        byte d => d + (byte)rhs() !,
                        string d => d + rhs() !.ToString(),
                        _ => throw new ArgumentOutOfRangeException()
                    });

                case DogeBinaryOperator.Subtract:
                    return(lhs switch
                    {
                        double d => (object)(d - (double)rhs() !),
                        float d => d - (float)rhs() !,
                        long d => d - (long)rhs() !,
                        int d => d - (int)rhs() !,
                        short d => d - (short)rhs() !,
                        byte d => d - (byte)rhs() !,
                        _ => throw new ArgumentOutOfRangeException()
                    });
        public DogeWhileStatement(DogeNode condition, DogeNode body, DogeFile file, Range <int> range) : base(file, range)
        {
            condition.Parent = this;
            Condition        = condition;

            body.Parent = this;
            Body        = body;
        }
        public DogeUnaryExpression(DogeUnaryOperator unaryOperator, DogeNode internalExpression,
                                   DogeFile file, Range <int> tokenRange) : base(file, tokenRange)
        {
            UnaryOperator = unaryOperator;

            internalExpression.Parent = this;
            InternalExpression        = internalExpression;
        }
        public DogeBinaryExpression(DogeBinaryOperator binaryOperator, DogeNode leftHandSide,
            DogeNode rightHandSide, DogeFile file) : base(file, Range<int>.ConcatOrdered(leftHandSide.TokenRange, rightHandSide.TokenRange))
        {
            BinaryOperator = binaryOperator;

            leftHandSide.Parent = this;
            LeftHandSide = leftHandSide;

            rightHandSide.Parent = this;
            RightHandSide = rightHandSide;
        }
Beispiel #5
0
        public static object?EvalStatement(DogeNode statement, Dictionary <string, object?> locals)
        {
            switch (statement)
            {
            case DogeStatementList statementList:
                var localsInner = locals.ToDictionary(x => x.Key, x => x.Value);
                foreach (var subStatement in statementList.Statements)
                {
                    EvalStatement(subStatement, localsInner);
                }
                break;

            case DogeWhileStatement whileStatement:
                while ((bool)EvalExpression(whileStatement.Condition, locals) !)
                {
                    EvalStatement(whileStatement.Body, locals);
                }
                break;

            case DogeIfStatement ifStatement:
                if ((bool)EvalExpression(ifStatement.Condition, locals) !)
                {
                    EvalStatement(ifStatement.Body, locals);
                }
                else
                {
                    if (ifStatement.Else != null)
                    {
                        EvalStatement(ifStatement.Else, locals);
                    }
                }
                break;

            case DogeLocalDeclarationStatement localDeclarationStatement:
                locals.Add(
                    localDeclarationStatement.Name,
                    localDeclarationStatement.Value != null
                            ? EvalExpression(localDeclarationStatement.Value, locals)
                            : null);
                break;

            case DogeExpressionStatement expressionStatement:
                EvalExpression(expressionStatement.Expression, locals);
                break;

            case DogeReturnStatement returnStatement:
                return(returnStatement.Value == null ? null : EvalExpression(returnStatement.Value, locals));
            }

            return(null);
        }
Beispiel #6
0
 public DogeFieldDefinition(DogeIdentifier name,
                            DogeMemberAccessExpression type,
                            DogeAccessibilityModifier modifier,
                            bool isReadonly,
                            DogeNode initialValue,
                            DogeFile file,
                            Range <int> tokenRange) : this(
         name,
         type,
         modifier,
         isReadonly,
         file,
         tokenRange)
 {
     initialValue.Parent = this;
     InitialValue        = initialValue;
 }
        public DogeIfStatement(
            DogeNode condition,
            DogeNode body,
            DogeNode? @else,
            DogeFile file,
            Range <int> tokenRange) : base(file, tokenRange)
        {
            condition.Parent = this;
            Condition        = condition;

            body.Parent = this;
            Body        = body;

            if (@else != null)
            {
                @else.Parent = this;
            }
            Else = @else;
        }
Beispiel #8
0
 public DogeExpressionStatement(DogeNode expression) : base(expression.File, expression.TokenRange)
 {
     expression.Parent = this;
     Expression        = expression;
 }
Beispiel #9
0
        private DogeNode ResolveExpressionSymbols(DogeNode node,
                                                  DogeSymbolTable symbolTable,
                                                  IDictionary <string, DogeLocalDeclarationStatement> locals,
                                                  ICollection <IList <string> > usingDefinitions,
                                                  IList <string> fullName)
        {
            void resolveSymbols(ref DogeNode node) =>
            node = ResolveExpressionSymbols(
                node,
                symbolTable,
                locals,
                usingDefinitions,
                fullName);

            switch (node)
            {
            case DogeBinaryExpression binaryExpression:
                resolveSymbols(ref binaryExpression.LeftHandSide);
                resolveSymbols(ref binaryExpression.RightHandSide);
                break;

            case DogeUnaryExpression unaryExpression:
                resolveSymbols(ref unaryExpression.InternalExpression);
                break;

            case DogeListExpression <DogeNode> listExpression:
                var nodeElements = listExpression.Elements.ToArray();
                for (int i = 0; i < nodeElements.Length; i++)
                {
                    resolveSymbols(ref nodeElements[i]);
                }
                break;

            case DogeListExpression <DogeMemberAccessorExpression> listExpression:
                DogeSymbolTable lastType  = symbolTable.GetSymbolTable(fullName);
                int             startSkip = 1;
                List <DogeMemberAccessorExpression> accumulator = new List <DogeMemberAccessorExpression>();

                if (!lastType.TryGetSymbol(listExpression.Elements.First().Name, out _))
                {
                    for (; startSkip <= listExpression.Elements.Count; startSkip++)
                    {
                        if (symbolTable.TryResolveSymbol(
                                listExpression.Elements.Select(x => x.Name).Take(startSkip).ToList(),
                                s => s.SymbolType == DogeSymbolType.Field ||
                                s.SymbolType == DogeSymbolType.Local ||
                                s.SymbolType == DogeSymbolType.Property ||
                                s.SymbolType == DogeSymbolType.Method,
                                s => s == DogeSymbolTableType.Type,
                                usingDefinitions,
                                out var lastTypeSymbol))
                        {
                            DogeMemberAccessorExpression last = listExpression.Elements.ElementAt(startSkip - 1);

                            if (lastTypeSymbol !.SymbolType != DogeSymbolType.Method)
                            {
                                if (last is DogeMethodCallStatement)
                                {
                                    throw new InvalidCastException();
                                }
                                lastType = symbolTable.GetSymbolTable(lastTypeSymbol.FullName);

                                Range <int> range = new Range <int>(listExpression.Elements.First().TokenRange.First, last.TokenRange.Last);
                                accumulator.Add(
                                    new DogeMemberAccessorExpression(
                                        new DogeIdentifier(
                                            new DogeToken(
                                                DogeTokenType.Identifier,
                                                string.Join('.', lastTypeSymbol.FullName),
                                                range.First),
                                            DogeFile.Console),
                                        false,
                                        false,
                                        listExpression.File,
                                        range)
                                {
                                    NameSymbol = new DogeSymbolNode(lastTypeSymbol !, listExpression.File, range)
                                });
                            }
Beispiel #10
0
        private void ResolveSymbols(DogeNode node,
                                    DogeSymbolTable symbolTable,
                                    IDictionary <string, DogeLocalDeclarationStatement> locals,
                                    ICollection <IList <string> > usingDefinitions,
                                    IList <string> fullName)
        {
            void resolveSymbols(DogeNode node) =>
            ResolveSymbols(
                node,
                symbolTable,
                locals,
                usingDefinitions,
                fullName);

            switch (node)
            {
            case DogeStatementList statementList:
                var localsOuter = locals.ToDictionary(x => x.Key, x => x.Value);
                foreach (var statement in statementList.Statements)
                {
                    resolveSymbols(statement);
                }
                locals = localsOuter;
                break;

            case DogeWhileStatement whileStatement:
                resolveSymbols(whileStatement.Condition);
                resolveSymbols(whileStatement.Body);
                break;

            case DogeIfStatement ifStatement:
                resolveSymbols(ifStatement.Condition);
                resolveSymbols(ifStatement.Body);
                if (ifStatement.Else != null)
                {
                    resolveSymbols(ifStatement.Else);
                }
                break;

            case DogeLocalDeclarationStatement localDeclarationStatement:
                if (localDeclarationStatement.Value != null)
                {
                    resolveSymbols(localDeclarationStatement.Value);
                }
                localDeclarationStatement.TypeSymbol = new DogeSymbolNode(symbolTable.ResolveSymbol(
                                                                              localDeclarationStatement.Type,
                                                                              s => s.SymbolType == DogeSymbolType.Type,
                                                                              s => s == DogeSymbolTableType.Namespace || s == DogeSymbolTableType.Type,
                                                                              usingDefinitions),
                                                                          localDeclarationStatement.File,
                                                                          localDeclarationStatement.TokenRange);
                locals.Add(localDeclarationStatement.Name, localDeclarationStatement);
                break;

            case DogeExpressionStatement expressionStatement:
                expressionStatement.Expression = ResolveExpressionSymbols(
                    expressionStatement.Expression,
                    symbolTable,
                    locals,
                    usingDefinitions,
                    fullName);
                break;
            }
        }