()
| 132 | private <N extends Node> N ctrl(N n) { return _scope.ctrl(n); } |
| 133 | |
| 134 | public void parse() { |
| 135 | |
| 136 | _scope.define(ScopeNode.CTRL, Type.CONTROL , false, null, _lexer); |
| 137 | _scope.define(ScopeNode.MEM0, TypeMem.BOT , false, null, _lexer); |
| 138 | _scope.define(ScopeNode.ARG0, TypeInteger.BOT, false, null, _lexer); |
| 139 | |
| 140 | ctrl(XCTRL); |
| 141 | _scope.mem(new MemMergeNode(false)); |
| 142 | |
| 143 | // Parse the sys import |
| 144 | _lexer = new Lexer(com.seaofnodes.simple.sys.SYS); |
| 145 | while( !_lexer.isEOF() ) { |
| 146 | parseStatement(); |
| 147 | _lexer.skipWhiteSpace(); |
| 148 | } |
| 149 | |
| 150 | // Reset lexer for program text |
| 151 | _lexer = new Lexer(_code._src); |
| 152 | _xScopes.push(_scope); |
| 153 | |
| 154 | // Parse whole program, as-if function header "{ int arg -> body }" |
| 155 | parseFunctionBody(_code._main,loc(),"arg"); |
| 156 | |
| 157 | // Kill an empty default main. Keep only if it was explicitly defined |
| 158 | // (programmer asked for a "main") or it has stuff (i.e. beginner |
| 159 | // default main). |
| 160 | FunNode main = _code.link(_code._main); |
| 161 | StopNode stop = _code._stop; |
| 162 | if( main.ret().expr()._type==Type.TOP && main.uctrl()==null ) { |
| 163 | // Kill an empty default main; so it does not attempt to put a |
| 164 | // "main" in any final ELF file |
| 165 | main.setDef(1,XCTRL); // Delete default start input |
| 166 | stop.delDef(stop._inputs.find(main.ret())); |
| 167 | } else { |
| 168 | // We have a non-empty default main. |
| 169 | // Check for an explicit main |
| 170 | for( Node n : stop._inputs ) |
| 171 | if( n instanceof FunNode fun && fun._name.equals("main") ) |
| 172 | // Found an explicit "main" AND we have a default "main" |
| 173 | throw error("Cannot define both an explicit main and a default main"); |
| 174 | main._name = "main"; |
| 175 | } |
| 176 | |
| 177 | if( !_lexer.isEOF() ) throw _errorSyntax("unexpected"); |
| 178 | |
| 179 | // Clean up and reset |
| 180 | _xScopes.pop(); |
| 181 | _scope.kill(); |
| 182 | for( StructNode init : INITS.values() ) |
| 183 | init.unkeep().kill(); |
| 184 | INITS.clear(); |
| 185 | stop.peephole(); |
| 186 | } |
| 187 | |
| 188 | /** |
| 189 | * Parses a function body, assuming the header is parsed. |
no test coverage detected