예제 #1
0
        public override Type visitVarDef(VariableDeclaration varDef, Environment env)
        {
            string     name         = varDef.name;
            Type       declaredType = scan(varDef.type, env);
            Expression init         = varDef.init;

            VarSymbol varSymbol = new VarSymbol(Kind.LOCAL, name, declaredType, env.enclFunc);

            varDef.symbol = varSymbol;
            if (init != null)
            {
                Type initType = analyzeExpr(init, env);
                if (!typings.isAssignableFrom(declaredType, initType))
                {
                    log.error(varDef.Pos, messages.varInitTypeMismatch, name, initType, declaredType);
                }
            }

            if (check.checkUniqueLocalVar(varDef.Pos, varSymbol, (WritableScope)env.scope))
            {
                ((WritableScope)env.scope).enter(varSymbol);
            }

            // probably unused
            return(declaredType);
        }
예제 #2
0
        public override void GenerateLValue(AsmCode asmCode, SymTable symTable)
        {
            var       t     = symTable.LookUpLevel(Value.ToString());
            VarSymbol v     = (VarSymbol)t?.Item1;
            int       level = t.Value.Item2;

            asmCode.Add(AsmCmd.Cmd.Mov, AsmReg.Reg.Eax, AsmReg.Reg.Ebp);
            while (level-- > 0)
            {
                asmCode.Add(
                    AsmCmd.Cmd.Mov,
                    AsmReg.Reg.Eax,
                    new AsmOffset(-8, 4, AsmReg.Reg.Eax));
            }
            asmCode.Add(
                AsmCmd.Cmd.Lea,
                AsmReg.Reg.Eax,
                new AsmOffset(v.Offset, 0, AsmReg.Reg.Eax));
            if (v is ParameterSymbol ps &&
                ps.ParameterModifier != ParameterModifier.Value)
            {
                asmCode.Add(
                    AsmCmd.Cmd.Mov,
                    AsmReg.Reg.Eax,
                    new AsmOffset(0, 4, AsmReg.Reg.Eax));
            }
            asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
        }
예제 #3
0
    private void declareSymbol(Var node, Type t)
    {
        ISymbol   typeSymbol = scope.find(t.name);
        string    varName    = node.name;
        VarSymbol varSymbol  = new VarSymbol(varName, typeSymbol.name);

        scope.define(varSymbol as ISymbol);
    }
예제 #4
0
 public bool checkUniqueLocalVar(DiagnosticPosition pos, VarSymbol varSymbol, WritableScope scope)
 {
     if (scope.getSymbolsByName(varSymbol.name, s => (s.kind & Kind.VAR) != 0).Any())
     {
         log.error(pos, messages.duplicateVar, varSymbol.name);
         return(false);
     }
     return(true);
 }
예제 #5
0
 public bool checkUniqueParam(DiagnosticPosition pos, VarSymbol param, Scope scope)
 {
     if (scope.getSymbolsByName(param.name, LookupKind.NON_RECURSIVE).Any())
     {
         log.error(pos, messages.duplicateParamName, param.name, scope.owner.name);
         return(false);
     }
     return(true);
 }
예제 #6
0
파일: FlowAnalysis.cs 프로젝트: irpbc/mj
        public override Exit visitIdent(Identifier ident, Environment env)
        {
            VarSymbol varSym = ident.symbol;

            if (varSym.kind == Kind.LOCAL && !env.isAssigned(varSym))
            {
                log.error(ident.Pos, messages.unassignedVariable, ident.name);
            }

            return(0);
        }
예제 #7
0
            private void enterParameter(VariableDeclaration varDef, WritableScope scope)
            {
                Type       varType = (Type)scan(varDef.type, scope);
                FuncSymbol func    = (FuncSymbol)scope.owner;
                VarSymbol  varSym  = new VarSymbol(Kind.PARAM, varDef.name, varType, func);

                varDef.symbol = varSym;

                func.parameters.Add(varSym);

                if (check.checkUniqueParam(varDef.Pos, varSym, scope))
                {
                    scope.enter(varSym);
                }
            }
예제 #8
0
        public override string Gen()
        {
            if (this.IsConstant())
            {
                return(this.Val().Gen());
            }
            string code = string.Empty;

            if (indexer == null)
            {
                code += value?.Gen() ?? string.Empty;
                code += expr?.Gen() ?? string.Empty;
                code += func?.Gen() ?? string.Empty;
            }
            else
            {
                VarSymbol arr = SymbolTable.FindVar((value as IdNode).name);
                code += indexer.Gen();
                code += $"mov\trbx, [rbp{(-arr.offsetInFun>0?"+":"")}{-arr.offsetInFun}]\n";
                code += $"lea\t{CodeGenUtils.CurrentStackTop64}, [rbx+{CodeGenUtils.CurrentStackTop64}*{arr.eleSize}]\n";
                switch (arr.eleSize)
                {
                case 1:
                    code += $"movsx\t{CodeGenUtils.CurrentStackTop64}, byte [{CodeGenUtils.CurrentStackTop64}]\n";
                    break;

                case 4:
                    code += $"mov\t{CodeGenUtils.CurrentStackTop32}, [{CodeGenUtils.CurrentStackTop64}]\n";
                    if (CodeGenUtils.CurrentStackTop32 == "eax")
                    {
                        code += "cdqe\n";
                    }
                    else
                    {
                        code += $"xchg\trax, {CodeGenUtils.CurrentStackTop64}\n";
                        code += "cdqe\n";
                        code += $"xchg\trax, {CodeGenUtils.CurrentStackTop64}\n";
                    }
                    break;

                case 8:
                    code += $"mov\t{CodeGenUtils.CurrentStackTop64}, [{CodeGenUtils.CurrentStackTop64}]\n";
                    break;
                }
            }

            return(code);
        }
예제 #9
0
파일: FlowAnalysis.cs 프로젝트: irpbc/mj
            public bool isAssigned(VarSymbol varSym)
            {
                bool contains = inits.Contains(varSym);

                if (contains)
                {
                    return(true);
                }

                if (parent != null)
                {
                    return(parent.isAssigned(varSym));
                }

                return(false);
            }
예제 #10
0
파일: FlowAnalysis.cs 프로젝트: irpbc/mj
        public override Exit visitAssign(AssignNode expr, Environment env)
        {
            analyzeExpr(expr.right, env);
            if (expr.left is Identifier id)
            {
                VarSymbol varSym = id.symbol;
                if (varSym.kind == Kind.LOCAL)
                {
                    env.assigned(varSym);
                }
            }
            else
            {
                analyzeExpr(expr.left, env);
            }

            return(0);
        }
예제 #11
0
        public override Type visitSelect(Select select, Environment env)
        {
            Type leftType = analyzeExpr(select.selectBase, env);

            if (leftType.IsError)
            {
                select.symbol = symtab.errorVarSymbol;
                return(symtab.errorType);
            }

            if (leftType.IsPrimitive)
            {
                log.error(select.Pos, messages.selectOnPrimitive);
                select.symbol = symtab.errorVarSymbol;
                return(symtab.errorType);
            }

            if (leftType.IsArray)
            {
                if (select.name != "length")
                {
                    log.error(select.Pos, "Arrays only have a \"length\" field");
                    return(symtab.errorType);
                }

                select.symbol = symtab.arrayLengthField;
                select.type   = symtab.arrayLengthField.type;
                return(select.type);
            }

            StructSymbol ssym  = ((StructType)leftType).symbol;
            VarSymbol    field = (VarSymbol)ssym.membersScope.findFirst(select.name);

            if (field == null)
            {
                log.error(select.Pos, messages.unknownField, select.name, ssym.name);
                select.symbol = symtab.errorVarSymbol;
                return(symtab.errorType);
            }

            select.symbol = field;
            select.type   = field.type;
            return(field.type);
        }
예제 #12
0
            /**
             * INFO: This is for fields. Another non-visitor routine is for function parameters.
             */
            public override object visitVarDef(VariableDeclaration varDef, WritableScope compoundScope)
            {
                WritableScope membersScope = ((StructSymbol)compoundScope.owner).membersScope;
                // TODO: Should be NON_RECURSIVE
                Symbol sym = membersScope.findFirst(varDef.name);

                if (sym != null)
                {
                    log.error(varDef.Pos, messages.duplicateMember, varDef.name, membersScope.owner.name);
                }
                else
                {
                    VarSymbol var = new VarSymbol(Kind.FIELD, varDef.name, (Type)scan(varDef.type, compoundScope),
                                                  membersScope.owner);
                    membersScope.enter(var);
                    varDef.symbol = var;
                }
                return(null);
            }
예제 #13
0
    public void visit(ProcDecl procDecl)
    {
        if (scope.scopeLevel == Dictionary.MAX_NEST_LEVEL)
        {
            throw new Exception(Dictionary.max_nest_level_exc);
        }
        ProcedureSymbol procSym = new ProcedureSymbol(procDecl.name);

        scope.define(procSym);
        scope = new ScopeSymbolTable(scope.scopeLevel + 1, scope);
        foreach (Param param in procDecl.parameters)
        {
            VarSymbol paramSymbol = createParamSymbol(param);
            scope.define(paramSymbol);
            procSym.parameters.Add(paramSymbol);
        }
        foreach (IAST child in procDecl.children)
        {
            child.accept(this);
        }
        scope = scope.globalScope;
    }
예제 #14
0
        private Type analyzeInvocation(FuncInvocation invocation, FuncSymbol fsym, Environment env)
        {
            IList <Expression> args = invocation.args;

            // check argument count
            IList <VarSymbol> paramSyms = fsym.parameters;

            if (fsym.isVararg ? args.Count < paramSyms.Count : args.Count != paramSyms.Count)
            {
                log.error(invocation.Pos, messages.wrongNumberOfArgs, fsym.name, paramSyms.Count, args.Count);
            }

            // check argument types
            int count = Math.Min(args.Count, paramSyms.Count);

            for (int i = 0; i < count; i++)
            {
                VarSymbol paramSym = paramSyms[i];
                Type      argType  = analyzeExpr(args[i], env);

                // we don't consider implicit numeric conversions for now
                if (!typings.isAssignableFrom(paramSym.type, argType))
                {
                    log.error(invocation.Pos, messages.paramTypeMismatch, fsym.name);
                }
            }

            for (int i = count; i < args.Count; ++i)
            {
                analyzeExpr(args[i], env);
            }

            fsym.isInvoked     = true;
            invocation.funcSym = fsym;
            invocation.type    = fsym.type.ReturnType;
            return(fsym.type.ReturnType);
        }
예제 #15
0
파일: FlowAnalysis.cs 프로젝트: irpbc/mj
 public void assigned(VarSymbol varSym)
 {
     inits.Add(varSym);
 }
예제 #16
0
        public override VarType Type()
        {
            VarSymbol item = SymbolTable.FindVar(name);

            return(item?.type ?? VarType.TYPE_ERROR);
        }