Brian Gaeke | c745b49 | 2003-12-10 04:33:07 +0000 | [diff] [blame] | 1 | //===-- StackerParser.y - Parser for Stacker programs -----------*- C++ -*-===// |
Chris Lattner | f608e85 | 2003-11-23 17:52:55 +0000 | [diff] [blame] | 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file was developed by the LLVM research group and is distributed under |
| 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
Brian Gaeke | c745b49 | 2003-12-10 04:33:07 +0000 | [diff] [blame] | 10 | // This file implements the bison parser for Stacker programs. |
Chris Lattner | f608e85 | 2003-11-23 17:52:55 +0000 | [diff] [blame] | 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Chris Lattner | f608e85 | 2003-11-23 17:52:55 +0000 | [diff] [blame] | 14 | %{ |
| 15 | #include "StackerCompiler.h" |
| 16 | #include "llvm/SymbolTable.h" |
| 17 | #include "llvm/Module.h" |
| 18 | #include "llvm/iTerminators.h" |
| 19 | #include "llvm/iMemory.h" |
| 20 | #include "llvm/iOperators.h" |
| 21 | #include "llvm/iPHINode.h" |
| 22 | #include "Support/STLExtras.h" |
| 23 | #include "Support/DepthFirstIterator.h" |
| 24 | #include <list> |
| 25 | #include <utility> |
| 26 | #include <algorithm> |
| 27 | |
| 28 | #define YYERROR_VERBOSE 1 |
| 29 | #define SCI StackerCompiler::TheInstance |
| 30 | |
| 31 | int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit |
| 32 | int yylex(); // declaration" of xxx warnings. |
| 33 | int yyparse(); |
| 34 | |
| 35 | %} |
| 36 | |
| 37 | %union |
| 38 | { |
| 39 | llvm::Module* ModuleVal; |
| 40 | llvm::Function* FunctionVal; |
| 41 | llvm::BasicBlock* BasicBlockVal; |
| 42 | uint32_t IntegerVal; |
| 43 | char* StringVal; |
| 44 | } |
| 45 | |
| 46 | /* Typed Productions */ |
| 47 | %type <ModuleVal> Module DefinitionList |
| 48 | %type <FunctionVal> Definition ForwardDef ColonDef MainDef |
| 49 | %type <FunctionVal> WordList |
| 50 | %type <BasicBlockVal> Word |
| 51 | |
| 52 | /* Typed Tokens */ |
| 53 | %token <IntegerVal> INTEGER |
| 54 | %token <StringVal> STRING IDENTIFIER |
| 55 | |
| 56 | /* Terminal Tokens */ |
| 57 | %token SEMI COLON FORWARD MAIN DUMP |
| 58 | %token TRUE FALSE LESS MORE LESS_EQUAL MORE_EQUAL NOT_EQUAL EQUAL |
| 59 | %token PLUS MINUS INCR DECR MULT DIV MODULUS NEGATE ABS MIN MAX STAR_SLASH |
| 60 | %token AND OR XOR LSHIFT RSHIFT |
| 61 | %token DROP DROP2 NIP NIP2 DUP DUP2 SWAP SWAP2 OVER OVER2 ROT ROT2 |
| 62 | %token RROT RROT2 TUCK TUCK2 ROLL PICK SELECT |
| 63 | %token MALLOC FREE GET PUT |
| 64 | %token IF ELSE ENDIF WHILE END RECURSE RETURN EXIT |
| 65 | %token TAB SPACE CR IN_STR IN_NUM IN_CHAR OUT_STR OUT_NUM OUT_CHAR |
| 66 | |
| 67 | /* Start Token */ |
| 68 | %start Module |
| 69 | |
| 70 | %% |
| 71 | |
| 72 | /* A module is just a DefinitionList */ |
| 73 | Module : { SCI->handle_module_start( ); } |
| 74 | DefinitionList { $$ = SCI->handle_module_end( $2 ); } ; |
| 75 | |
| 76 | /* A Definitionlist is just a sequence of definitions */ |
| 77 | DefinitionList : DefinitionList Definition { $$ = SCI->handle_definition_list_end( $1, $2 ); } |
| 78 | | /* empty */ { $$ = SCI->handle_definition_list_start(); } ; |
| 79 | |
| 80 | /* A definition can be one of three flavors */ |
| 81 | Definition : ForwardDef { $$ = $1; } |
| 82 | | ColonDef { $$ = $1; } |
| 83 | | MainDef { $$ = $1; } ; |
| 84 | |
| 85 | /* Forward definitions just introduce a name */ |
| 86 | ForwardDef : FORWARD IDENTIFIER SEMI { $$ = SCI->handle_forward( $2 ); } ; |
| 87 | |
| 88 | /* The main definition has to generate additional code so we treat it specially */ |
| 89 | MainDef : COLON MAIN WordList SEMI { $$ = SCI->handle_main_definition($3); } ; |
| 90 | |
| 91 | /* Regular definitions have a name and a WordList */ |
| 92 | ColonDef : COLON IDENTIFIER WordList SEMI { $$ = SCI->handle_definition( $2, $3 ); } ; |
| 93 | |
| 94 | /* A WordList is just a sequence of words */ |
| 95 | WordList : WordList Word { $$ = SCI->handle_word_list_end( $1, $2 ); } |
Chris Lattner | 1b9ce47 | 2003-12-08 20:15:33 +0000 | [diff] [blame] | 96 | | /* empty */ { $$ = SCI->handle_word_list_start(); } ; |
Chris Lattner | f608e85 | 2003-11-23 17:52:55 +0000 | [diff] [blame] | 97 | |
| 98 | /* A few "words" have a funky syntax */ |
| 99 | /* FIXME: The body of compound words can currently only be function calls */ |
| 100 | /* This is not acceptable, it should be a WordList, but that produces a Function */ |
| 101 | /* Which is hard to merge into the function the compound statement is working on */ |
| 102 | Word : IF IDENTIFIER ELSE IDENTIFIER ENDIF { $$ = SCI->handle_if( $2, $4 ); } |
| 103 | | IF IDENTIFIER ENDIF { $$ = SCI->handle_if( $2 ); } |
| 104 | | WHILE IDENTIFIER END { $$ = SCI->handle_while( $2 ); } ; |
| 105 | |
| 106 | /* A few words are handled specially */ |
| 107 | Word : IDENTIFIER { $$ = SCI->handle_identifier( $1 ); } ; |
| 108 | Word : STRING { $$ = SCI->handle_string( $1 ); } ; |
| 109 | Word : INTEGER { $$ = SCI->handle_integer( $1 ); } ; |
| 110 | |
| 111 | /* Everything else is a terminal symbol and goes to handle_word */ |
| 112 | Word : TRUE { $$ = SCI->handle_word( TRUE ); } ; |
| 113 | Word : FALSE { $$ = SCI->handle_word( FALSE ); } ; |
| 114 | Word : LESS { $$ = SCI->handle_word( LESS ); } ; |
| 115 | Word : MORE { $$ = SCI->handle_word( MORE ); } ; |
| 116 | Word : LESS_EQUAL { $$ = SCI->handle_word( LESS_EQUAL ); } ; |
| 117 | Word : MORE_EQUAL { $$ = SCI->handle_word( MORE_EQUAL ); } ; |
| 118 | Word : NOT_EQUAL { $$ = SCI->handle_word( NOT_EQUAL ); } ; |
| 119 | Word : EQUAL { $$ = SCI->handle_word( EQUAL ); } ; |
| 120 | Word : PLUS { $$ = SCI->handle_word( PLUS ); } ; |
| 121 | Word : MINUS { $$ = SCI->handle_word( MINUS ); } ; |
| 122 | Word : INCR { $$ = SCI->handle_word( INCR ); } ; |
| 123 | Word : DECR { $$ = SCI->handle_word( DECR ); } ; |
| 124 | Word : MULT { $$ = SCI->handle_word( MULT ); } ; |
| 125 | Word : DIV { $$ = SCI->handle_word( DIV ); } ; |
| 126 | Word : MODULUS { $$ = SCI->handle_word( MODULUS ); } ; |
| 127 | Word : NEGATE { $$ = SCI->handle_word( NEGATE ); } ; |
| 128 | Word : ABS { $$ = SCI->handle_word( ABS ); } ; |
| 129 | Word : MIN { $$ = SCI->handle_word( MIN ); } ; |
| 130 | Word : MAX { $$ = SCI->handle_word( MAX ); } ; |
| 131 | Word : STAR_SLASH { $$ = SCI->handle_word( STAR_SLASH ); } ; |
| 132 | Word : AND { $$ = SCI->handle_word( AND ); } ; |
| 133 | Word : OR { $$ = SCI->handle_word( OR ); } ; |
| 134 | Word : XOR { $$ = SCI->handle_word( XOR ); } ; |
| 135 | Word : LSHIFT { $$ = SCI->handle_word( LSHIFT ); } ; |
| 136 | Word : RSHIFT { $$ = SCI->handle_word( RSHIFT ); } ; |
| 137 | Word : DROP { $$ = SCI->handle_word( DROP ); } ; |
| 138 | Word : DROP2 { $$ = SCI->handle_word( DROP2 ); } ; |
| 139 | Word : NIP { $$ = SCI->handle_word( NIP ); } ; |
| 140 | Word : NIP2 { $$ = SCI->handle_word( NIP2 ); } ; |
| 141 | Word : DUP { $$ = SCI->handle_word( DUP ); } ; |
| 142 | Word : DUP2 { $$ = SCI->handle_word( DUP2 ); } ; |
| 143 | Word : SWAP { $$ = SCI->handle_word( SWAP ); } ; |
| 144 | Word : SWAP2 { $$ = SCI->handle_word( SWAP2 ); } ; |
| 145 | Word : OVER { $$ = SCI->handle_word( OVER ); } ; |
| 146 | Word : OVER2 { $$ = SCI->handle_word( OVER2 ); } ; |
| 147 | Word : ROT { $$ = SCI->handle_word( ROT ); } ; |
| 148 | Word : ROT2 { $$ = SCI->handle_word( ROT2 ); } ; |
| 149 | Word : RROT { $$ = SCI->handle_word( RROT ); } ; |
| 150 | Word : RROT2 { $$ = SCI->handle_word( RROT2 ); } ; |
| 151 | Word : TUCK { $$ = SCI->handle_word( TUCK ); } ; |
| 152 | Word : TUCK2 { $$ = SCI->handle_word( TUCK2 ); } ; |
| 153 | Word : ROLL { $$ = SCI->handle_word( ROLL ); } ; |
| 154 | Word : PICK { $$ = SCI->handle_word( PICK ); } ; |
| 155 | Word : SELECT { $$ = SCI->handle_word( SELECT ); } ; |
| 156 | Word : MALLOC { $$ = SCI->handle_word( MALLOC ); } ; |
| 157 | Word : FREE { $$ = SCI->handle_word( FREE ); } ; |
| 158 | Word : GET { $$ = SCI->handle_word( GET ); } ; |
| 159 | Word : PUT { $$ = SCI->handle_word( PUT ); } ; |
| 160 | Word : RECURSE { $$ = SCI->handle_word( RECURSE ); } ; |
| 161 | Word : RETURN { $$ = SCI->handle_word( RETURN ); } ; |
| 162 | Word : EXIT { $$ = SCI->handle_word( EXIT ); } ; |
| 163 | Word : TAB { $$ = SCI->handle_word( TAB ); }; |
| 164 | Word : SPACE { $$ = SCI->handle_word( SPACE ); } ; |
| 165 | Word : CR { $$ = SCI->handle_word( CR ); } ; |
| 166 | Word : IN_STR { $$ = SCI->handle_word( IN_STR ); } ; |
| 167 | Word : IN_NUM { $$ = SCI->handle_word( IN_NUM ); } ; |
| 168 | Word : IN_CHAR { $$ = SCI->handle_word( IN_CHAR ); } ; |
| 169 | Word : OUT_STR { $$ = SCI->handle_word( OUT_STR ); } ; |
| 170 | Word : OUT_NUM { $$ = SCI->handle_word( OUT_NUM ); } ; |
| 171 | Word : OUT_CHAR { $$ = SCI->handle_word( OUT_CHAR ); } ; |
| 172 | Word : DUMP { $$ = SCI->handle_word( DUMP ); } ; |
| 173 | |
| 174 | %% |
| 175 | |
| 176 | /* Handle messages a little more nicely than the default yyerror */ |
| 177 | int yyerror(const char *ErrorMsg) { |
| 178 | std::string where |
| 179 | = std::string((SCI->filename() == "-") ? std::string("<stdin>") : SCI->filename()) |
| 180 | + ":" + utostr((unsigned) Stackerlineno ) + ": "; |
| 181 | std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading "; |
| 182 | if (yychar == YYEMPTY) |
| 183 | errMsg += "end-of-file."; |
| 184 | else |
| 185 | errMsg += "token: '" + std::string(Stackertext, Stackerleng) + "'"; |
| 186 | StackerCompiler::ThrowException(errMsg); |
| 187 | return 0; |
| 188 | } |