blob: 59139122a28923bf3542cabfb69a853dc7996ced [file] [log] [blame]
Brian Gaekec745b492003-12-10 04:33:07 +00001//===-- StackerParser.y - Parser for Stacker programs -----------*- C++ -*-===//
Chris Lattnerf608e852003-11-23 17:52:55 +00002//
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 Gaekec745b492003-12-10 04:33:07 +000010// This file implements the bison parser for Stacker programs.
Chris Lattnerf608e852003-11-23 17:52:55 +000011//
12//===----------------------------------------------------------------------===//
13
Chris Lattnerf608e852003-11-23 17:52:55 +000014%{
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
31int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit
32int yylex(); // declaration" of xxx warnings.
33int 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 */
73Module : { SCI->handle_module_start( ); }
74 DefinitionList { $$ = SCI->handle_module_end( $2 ); } ;
75
76/* A Definitionlist is just a sequence of definitions */
77DefinitionList : 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 */
81Definition : ForwardDef { $$ = $1; }
82 | ColonDef { $$ = $1; }
83 | MainDef { $$ = $1; } ;
84
85/* Forward definitions just introduce a name */
86ForwardDef : FORWARD IDENTIFIER SEMI { $$ = SCI->handle_forward( $2 ); } ;
87
88/* The main definition has to generate additional code so we treat it specially */
89MainDef : COLON MAIN WordList SEMI { $$ = SCI->handle_main_definition($3); } ;
90
91/* Regular definitions have a name and a WordList */
92ColonDef : COLON IDENTIFIER WordList SEMI { $$ = SCI->handle_definition( $2, $3 ); } ;
93
94/* A WordList is just a sequence of words */
95WordList : WordList Word { $$ = SCI->handle_word_list_end( $1, $2 ); }
Chris Lattner1b9ce472003-12-08 20:15:33 +000096 | /* empty */ { $$ = SCI->handle_word_list_start(); } ;
Chris Lattnerf608e852003-11-23 17:52:55 +000097
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 */
102Word : 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 */
107Word : IDENTIFIER { $$ = SCI->handle_identifier( $1 ); } ;
108Word : STRING { $$ = SCI->handle_string( $1 ); } ;
109Word : INTEGER { $$ = SCI->handle_integer( $1 ); } ;
110
111/* Everything else is a terminal symbol and goes to handle_word */
112Word : TRUE { $$ = SCI->handle_word( TRUE ); } ;
113Word : FALSE { $$ = SCI->handle_word( FALSE ); } ;
114Word : LESS { $$ = SCI->handle_word( LESS ); } ;
115Word : MORE { $$ = SCI->handle_word( MORE ); } ;
116Word : LESS_EQUAL { $$ = SCI->handle_word( LESS_EQUAL ); } ;
117Word : MORE_EQUAL { $$ = SCI->handle_word( MORE_EQUAL ); } ;
118Word : NOT_EQUAL { $$ = SCI->handle_word( NOT_EQUAL ); } ;
119Word : EQUAL { $$ = SCI->handle_word( EQUAL ); } ;
120Word : PLUS { $$ = SCI->handle_word( PLUS ); } ;
121Word : MINUS { $$ = SCI->handle_word( MINUS ); } ;
122Word : INCR { $$ = SCI->handle_word( INCR ); } ;
123Word : DECR { $$ = SCI->handle_word( DECR ); } ;
124Word : MULT { $$ = SCI->handle_word( MULT ); } ;
125Word : DIV { $$ = SCI->handle_word( DIV ); } ;
126Word : MODULUS { $$ = SCI->handle_word( MODULUS ); } ;
127Word : NEGATE { $$ = SCI->handle_word( NEGATE ); } ;
128Word : ABS { $$ = SCI->handle_word( ABS ); } ;
129Word : MIN { $$ = SCI->handle_word( MIN ); } ;
130Word : MAX { $$ = SCI->handle_word( MAX ); } ;
131Word : STAR_SLASH { $$ = SCI->handle_word( STAR_SLASH ); } ;
132Word : AND { $$ = SCI->handle_word( AND ); } ;
133Word : OR { $$ = SCI->handle_word( OR ); } ;
134Word : XOR { $$ = SCI->handle_word( XOR ); } ;
135Word : LSHIFT { $$ = SCI->handle_word( LSHIFT ); } ;
136Word : RSHIFT { $$ = SCI->handle_word( RSHIFT ); } ;
137Word : DROP { $$ = SCI->handle_word( DROP ); } ;
138Word : DROP2 { $$ = SCI->handle_word( DROP2 ); } ;
139Word : NIP { $$ = SCI->handle_word( NIP ); } ;
140Word : NIP2 { $$ = SCI->handle_word( NIP2 ); } ;
141Word : DUP { $$ = SCI->handle_word( DUP ); } ;
142Word : DUP2 { $$ = SCI->handle_word( DUP2 ); } ;
143Word : SWAP { $$ = SCI->handle_word( SWAP ); } ;
144Word : SWAP2 { $$ = SCI->handle_word( SWAP2 ); } ;
145Word : OVER { $$ = SCI->handle_word( OVER ); } ;
146Word : OVER2 { $$ = SCI->handle_word( OVER2 ); } ;
147Word : ROT { $$ = SCI->handle_word( ROT ); } ;
148Word : ROT2 { $$ = SCI->handle_word( ROT2 ); } ;
149Word : RROT { $$ = SCI->handle_word( RROT ); } ;
150Word : RROT2 { $$ = SCI->handle_word( RROT2 ); } ;
151Word : TUCK { $$ = SCI->handle_word( TUCK ); } ;
152Word : TUCK2 { $$ = SCI->handle_word( TUCK2 ); } ;
153Word : ROLL { $$ = SCI->handle_word( ROLL ); } ;
154Word : PICK { $$ = SCI->handle_word( PICK ); } ;
155Word : SELECT { $$ = SCI->handle_word( SELECT ); } ;
156Word : MALLOC { $$ = SCI->handle_word( MALLOC ); } ;
157Word : FREE { $$ = SCI->handle_word( FREE ); } ;
158Word : GET { $$ = SCI->handle_word( GET ); } ;
159Word : PUT { $$ = SCI->handle_word( PUT ); } ;
160Word : RECURSE { $$ = SCI->handle_word( RECURSE ); } ;
161Word : RETURN { $$ = SCI->handle_word( RETURN ); } ;
162Word : EXIT { $$ = SCI->handle_word( EXIT ); } ;
163Word : TAB { $$ = SCI->handle_word( TAB ); };
164Word : SPACE { $$ = SCI->handle_word( SPACE ); } ;
165Word : CR { $$ = SCI->handle_word( CR ); } ;
166Word : IN_STR { $$ = SCI->handle_word( IN_STR ); } ;
167Word : IN_NUM { $$ = SCI->handle_word( IN_NUM ); } ;
168Word : IN_CHAR { $$ = SCI->handle_word( IN_CHAR ); } ;
169Word : OUT_STR { $$ = SCI->handle_word( OUT_STR ); } ;
170Word : OUT_NUM { $$ = SCI->handle_word( OUT_NUM ); } ;
171Word : OUT_CHAR { $$ = SCI->handle_word( OUT_CHAR ); } ;
172Word : DUMP { $$ = SCI->handle_word( DUMP ); } ;
173
174%%
175
176/* Handle messages a little more nicely than the default yyerror */
177int 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}