public virtual DataType ProcessIdentExpression(IdentExpressionAst identExpression)
        {
            var name = identExpression.IdentifierToken.Value;

            if (!SymbolScope.FindSymbolDeep(name, out Symbol symbol))
            {
                throw new SemanticException($"Symbol {name} not exist");
            }

            if (!(symbol is VariableSymbol variableSymbol))
            {
                throw new SemanticException($"Symbol {name} is not const/var");
            }

            // All check ok

            if (CodeGenerationEnabled)
            {
                // load-variable-addr
                if (variableSymbol.IsGlobal)
                {
                    var id = variableSymbol.GlobalVariableBuilder.Id;
                    ExpressionBucket.Add(new object[] { "globa", id });
                }
                else
                {
                    if (variableSymbol.LocalLocation.IsArgument)
                    {
                        var id = variableSymbol.LocalLocation.Id;
                        if (CurrentFunction.ReturnType != DataType.Void)
                        {
                            id++;// because arg0 is ret val
                        }
                        var instruction = Instruction.Pack("arga", id);
                        instruction.Comment = variableSymbol.Name + " (ident-expr)";
                        ExpressionBucket.Add(instruction);
                    }
                    else
                    {
                        // 局部变量
                        var id = variableSymbol.LocalLocation.Id;
                        ExpressionBucket.Add(new object[] { "loca", id });
                    }
                }

                // de-reference
                ExpressionBucket.Add(Instruction.Pack("load.64"));
            }

            return(variableSymbol.Type);
        }
示例#2
0
        void ProcessIdentExpression_throws_when_symbol_not_found()
        {
            var scope = new SymbolScope();

            var name = new IdentifierToken("aCounter", default);

            var ast = new IdentExpressionAst(name);

            var generator = ConfigureGenerator(scope, mock =>
            {
            });

            Assert.Throws <SemanticException>(() => generator.ProcessIdentExpression(ast));
        }
示例#3
0
        void ProcessIdentExpression_returns_type_when_constvar_ok()
        {
            var scope      = new SymbolScope();
            var funcSymbol = new VariableSymbol("aCounter", true, false, DataType.Long);

            scope.AddSymbol(funcSymbol);

            var name = new IdentifierToken("aCounter", default);

            var ast = new IdentExpressionAst(name);

            var generator = ConfigureGenerator(scope, mock =>
            {
            });

            Assert.Equal(DataType.Long, generator.ProcessIdentExpression(ast));
        }
示例#4
0
        void ProcessIdentExpression_throws_when_symbol_not_var_or_const()
        {
            var scope      = new SymbolScope();
            var funcSymbol = new FunctionSymbol("aCounter", DataType.Void, new DataType[0]);

            scope.AddSymbol(funcSymbol);

            var name = new IdentifierToken("aCounter", default);

            var ast = new IdentExpressionAst(name);

            var generator = ConfigureGenerator(scope, mock =>
            {
            });

            Assert.Throws <SemanticException>(() => generator.ProcessIdentExpression(ast));
        }