1 //===-- llvmAsmParser.y - Parser for llvm assembly files --------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // This file implements the bison parser for LLVM assembly languages files.
12 //===----------------------------------------------------------------------===//
17 #include "StackerCompiler.h"
18 #include "llvm/SymbolTable.h"
19 #include "llvm/Module.h"
20 #include "llvm/iTerminators.h"
21 #include "llvm/iMemory.h"
22 #include "llvm/iOperators.h"
23 #include "llvm/iPHINode.h"
24 #include "Support/STLExtras.h"
25 #include "Support/DepthFirstIterator.h"
30 #define YYERROR_VERBOSE 1
31 #define SCI StackerCompiler::TheInstance
33 int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit
34 int yylex(); // declaration" of xxx warnings.
41 llvm::Module* ModuleVal;
42 llvm::Function* FunctionVal;
43 llvm::BasicBlock* BasicBlockVal;
48 /* Typed Productions */
49 %type <ModuleVal> Module DefinitionList
50 %type <FunctionVal> Definition ForwardDef ColonDef MainDef
51 %type <FunctionVal> WordList
52 %type <BasicBlockVal> Word
55 %token <IntegerVal> INTEGER
56 %token <StringVal> STRING IDENTIFIER
59 %token SEMI COLON FORWARD MAIN DUMP
60 %token TRUE FALSE LESS MORE LESS_EQUAL MORE_EQUAL NOT_EQUAL EQUAL
61 %token PLUS MINUS INCR DECR MULT DIV MODULUS NEGATE ABS MIN MAX STAR_SLASH
62 %token AND OR XOR LSHIFT RSHIFT
63 %token DROP DROP2 NIP NIP2 DUP DUP2 SWAP SWAP2 OVER OVER2 ROT ROT2
64 %token RROT RROT2 TUCK TUCK2 ROLL PICK SELECT
65 %token MALLOC FREE GET PUT
66 %token IF ELSE ENDIF WHILE END RECURSE RETURN EXIT
67 %token TAB SPACE CR IN_STR IN_NUM IN_CHAR OUT_STR OUT_NUM OUT_CHAR
74 /* A module is just a DefinitionList */
75 Module : { SCI->handle_module_start( ); }
76 DefinitionList { $$ = SCI->handle_module_end( $2 ); } ;
78 /* A Definitionlist is just a sequence of definitions */
79 DefinitionList : DefinitionList Definition { $$ = SCI->handle_definition_list_end( $1, $2 ); }
80 | /* empty */ { $$ = SCI->handle_definition_list_start(); } ;
82 /* A definition can be one of three flavors */
83 Definition : ForwardDef { $$ = $1; }
84 | ColonDef { $$ = $1; }
85 | MainDef { $$ = $1; } ;
87 /* Forward definitions just introduce a name */
88 ForwardDef : FORWARD IDENTIFIER SEMI { $$ = SCI->handle_forward( $2 ); } ;
90 /* The main definition has to generate additional code so we treat it specially */
91 MainDef : COLON MAIN WordList SEMI { $$ = SCI->handle_main_definition($3); } ;
93 /* Regular definitions have a name and a WordList */
94 ColonDef : COLON IDENTIFIER WordList SEMI { $$ = SCI->handle_definition( $2, $3 ); } ;
96 /* A WordList is just a sequence of words */
97 WordList : WordList Word { $$ = SCI->handle_word_list_end( $1, $2 ); }
98 | /* empty */ { $$ = SCI->handle_word_list_start() } ;
100 /* A few "words" have a funky syntax */
101 /* FIXME: The body of compound words can currently only be function calls */
102 /* This is not acceptable, it should be a WordList, but that produces a Function */
103 /* Which is hard to merge into the function the compound statement is working on */
104 Word : IF IDENTIFIER ELSE IDENTIFIER ENDIF { $$ = SCI->handle_if( $2, $4 ); }
105 | IF IDENTIFIER ENDIF { $$ = SCI->handle_if( $2 ); }
106 | WHILE IDENTIFIER END { $$ = SCI->handle_while( $2 ); } ;
108 /* A few words are handled specially */
109 Word : IDENTIFIER { $$ = SCI->handle_identifier( $1 ); } ;
110 Word : STRING { $$ = SCI->handle_string( $1 ); } ;
111 Word : INTEGER { $$ = SCI->handle_integer( $1 ); } ;
113 /* Everything else is a terminal symbol and goes to handle_word */
114 Word : TRUE { $$ = SCI->handle_word( TRUE ); } ;
115 Word : FALSE { $$ = SCI->handle_word( FALSE ); } ;
116 Word : LESS { $$ = SCI->handle_word( LESS ); } ;
117 Word : MORE { $$ = SCI->handle_word( MORE ); } ;
118 Word : LESS_EQUAL { $$ = SCI->handle_word( LESS_EQUAL ); } ;
119 Word : MORE_EQUAL { $$ = SCI->handle_word( MORE_EQUAL ); } ;
120 Word : NOT_EQUAL { $$ = SCI->handle_word( NOT_EQUAL ); } ;
121 Word : EQUAL { $$ = SCI->handle_word( EQUAL ); } ;
122 Word : PLUS { $$ = SCI->handle_word( PLUS ); } ;
123 Word : MINUS { $$ = SCI->handle_word( MINUS ); } ;
124 Word : INCR { $$ = SCI->handle_word( INCR ); } ;
125 Word : DECR { $$ = SCI->handle_word( DECR ); } ;
126 Word : MULT { $$ = SCI->handle_word( MULT ); } ;
127 Word : DIV { $$ = SCI->handle_word( DIV ); } ;
128 Word : MODULUS { $$ = SCI->handle_word( MODULUS ); } ;
129 Word : NEGATE { $$ = SCI->handle_word( NEGATE ); } ;
130 Word : ABS { $$ = SCI->handle_word( ABS ); } ;
131 Word : MIN { $$ = SCI->handle_word( MIN ); } ;
132 Word : MAX { $$ = SCI->handle_word( MAX ); } ;
133 Word : STAR_SLASH { $$ = SCI->handle_word( STAR_SLASH ); } ;
134 Word : AND { $$ = SCI->handle_word( AND ); } ;
135 Word : OR { $$ = SCI->handle_word( OR ); } ;
136 Word : XOR { $$ = SCI->handle_word( XOR ); } ;
137 Word : LSHIFT { $$ = SCI->handle_word( LSHIFT ); } ;
138 Word : RSHIFT { $$ = SCI->handle_word( RSHIFT ); } ;
139 Word : DROP { $$ = SCI->handle_word( DROP ); } ;
140 Word : DROP2 { $$ = SCI->handle_word( DROP2 ); } ;
141 Word : NIP { $$ = SCI->handle_word( NIP ); } ;
142 Word : NIP2 { $$ = SCI->handle_word( NIP2 ); } ;
143 Word : DUP { $$ = SCI->handle_word( DUP ); } ;
144 Word : DUP2 { $$ = SCI->handle_word( DUP2 ); } ;
145 Word : SWAP { $$ = SCI->handle_word( SWAP ); } ;
146 Word : SWAP2 { $$ = SCI->handle_word( SWAP2 ); } ;
147 Word : OVER { $$ = SCI->handle_word( OVER ); } ;
148 Word : OVER2 { $$ = SCI->handle_word( OVER2 ); } ;
149 Word : ROT { $$ = SCI->handle_word( ROT ); } ;
150 Word : ROT2 { $$ = SCI->handle_word( ROT2 ); } ;
151 Word : RROT { $$ = SCI->handle_word( RROT ); } ;
152 Word : RROT2 { $$ = SCI->handle_word( RROT2 ); } ;
153 Word : TUCK { $$ = SCI->handle_word( TUCK ); } ;
154 Word : TUCK2 { $$ = SCI->handle_word( TUCK2 ); } ;
155 Word : ROLL { $$ = SCI->handle_word( ROLL ); } ;
156 Word : PICK { $$ = SCI->handle_word( PICK ); } ;
157 Word : SELECT { $$ = SCI->handle_word( SELECT ); } ;
158 Word : MALLOC { $$ = SCI->handle_word( MALLOC ); } ;
159 Word : FREE { $$ = SCI->handle_word( FREE ); } ;
160 Word : GET { $$ = SCI->handle_word( GET ); } ;
161 Word : PUT { $$ = SCI->handle_word( PUT ); } ;
162 Word : RECURSE { $$ = SCI->handle_word( RECURSE ); } ;
163 Word : RETURN { $$ = SCI->handle_word( RETURN ); } ;
164 Word : EXIT { $$ = SCI->handle_word( EXIT ); } ;
165 Word : TAB { $$ = SCI->handle_word( TAB ); };
166 Word : SPACE { $$ = SCI->handle_word( SPACE ); } ;
167 Word : CR { $$ = SCI->handle_word( CR ); } ;
168 Word : IN_STR { $$ = SCI->handle_word( IN_STR ); } ;
169 Word : IN_NUM { $$ = SCI->handle_word( IN_NUM ); } ;
170 Word : IN_CHAR { $$ = SCI->handle_word( IN_CHAR ); } ;
171 Word : OUT_STR { $$ = SCI->handle_word( OUT_STR ); } ;
172 Word : OUT_NUM { $$ = SCI->handle_word( OUT_NUM ); } ;
173 Word : OUT_CHAR { $$ = SCI->handle_word( OUT_CHAR ); } ;
174 Word : DUMP { $$ = SCI->handle_word( DUMP ); } ;
178 /* Handle messages a little more nicely than the default yyerror */
179 int yyerror(const char *ErrorMsg) {
181 = std::string((SCI->filename() == "-") ? std::string("<stdin>") : SCI->filename())
182 + ":" + utostr((unsigned) Stackerlineno ) + ": ";
183 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
184 if (yychar == YYEMPTY)
185 errMsg += "end-of-file.";
187 errMsg += "token: '" + std::string(Stackertext, Stackerleng) + "'";
188 StackerCompiler::ThrowException(errMsg);