%{ #include #include #include #include #include #include "ast.hpp" #define YYDEBUG 1 using namespace std; int yylex(); void yyerror(string s) { cerr << s << endl; exit(EXIT_FAILURE); } int counter = 0; %} %union { double d; string *s; ExprAST *e; vector *v; vector *v1; PrototypeAST *p; vector > *v2; pair *p1; } %token def_token extern_token if_token then_token else_token for_token in_token var_token %token id_token %token num_token %type E %type EArray Arguments %type Args %type

Potpis %type NizInic %type Inic %left else_token in_token %left ':' %right '=' %left '<' '>' %left '+' '-' %left '*' '/' %% Program: Program Statement ';' | Statement ';' ; Statement: def_token Potpis E { FunctionAST* f = new FunctionAST(*$2, $3); delete $2; f->codegen(); delete f; } | E { PrototypeAST p(to_string(counter++), vector()); FunctionAST *f = new FunctionAST(p, $1); f->codegen(); delete f; } | extern_token Potpis { $2->codegen(); delete $2; } ; Potpis: id_token '(' Args ')' { $$ = new PrototypeAST(*$1, *$3); delete $1; delete $3; } ; Args: Args id_token { $$ = $1; $$->push_back(*$2); delete $2; } | { $$ = new vector(); } ; E: E '+' E { $$ = new AddExprAST($1, $3); } | E '-' E { $$ = new SubExprAST($1, $3); } | E '*' E { $$ = new MulExprAST($1, $3); } | E '/' E { $$ = new DivExprAST($1, $3); } | E '<' E { $$ = new LTExprAST($1, $3); } | E '>' E { $$ = new GTExprAST($1, $3); } | E ':' E { $$ = new SeqExprAST($1, $3); } | '(' E ')' { $$ = $2; } | id_token '=' E { $$ = new AssignExprAST(*$1, $3); delete $1; } | num_token { $$ = new NumberExprAST($1); } | id_token { $$ = new VariableExprAST(*$1); delete $1; } | id_token '(' Arguments ')' { $$ = new CallExprAST(*$1, *$3); delete $1; delete $3; } | if_token E then_token E else_token E { $$ = new IfExprAST($2, $4, $6); } | for_token id_token '=' E ',' E ',' E in_token E { $$ = new ForExprAST(*$2, $4, $6, $8, $10); delete $2; } | for_token id_token '=' E ',' E in_token E { $$ = new ForExprAST(*$2, $4, $6, NULL, $8); delete $2; } | var_token NizInic in_token E { $$ = new VarExprAST(*$2, $4); delete $2; } ; NizInic: NizInic ',' Inic { $$ = $1; $$->push_back(*$3); delete $3; } | Inic { $$ = new vector >(); $$->push_back(*$1); delete $1; } ; Inic: id_token '=' E { $$ = new pair(*$1, $3); delete $1; } | id_token { $$ = new pair(*$1, NULL); delete $1; } ; Arguments: EArray { $$ = $1; } | { $$ = new vector(); } ; EArray: EArray ',' E { $$ = $1; $$->push_back($3); } | E { $$ = new vector(); $$->push_back($1); } ; %% extern Module* TheModule; extern LLVMContext TheContext; int main() { //yydebug = 1; InitializeModuleAndPassManager(); yyparse(); TheModule->dump(); string TargetTriple = "x86_64-pc-linux-gnu"; LLVMInitializeAllTargetInfos(); LLVMInitializeAllTargets(); LLVMInitializeAllTargetMCs(); LLVMInitializeAllAsmParsers(); LLVMInitializeAllAsmPrinters(); string Error; auto Target = TargetRegistry::lookupTarget(TargetTriple, Error); // Print an error and exit if we couldn't find the requested target. // This generally occurs if we've forgotten to initialise the // TargetRegistry or we have a bogus target triple. if (!Target) { cerr << Error; return 1; } auto CPU = "generic"; auto Features = ""; TargetOptions opt; auto RM = Reloc::Model(); auto TargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM); TheModule->setDataLayout(TargetMachine->createDataLayout()); TheModule->setTargetTriple(TargetTriple); string Filename = "output.o"; error_code EC; raw_fd_ostream dest(Filename, EC, sys::fs::F_None); if (EC) { cerr << "Could not open file: " << EC.message(); return 1; } legacy::PassManager pass; auto FileType = TargetMachine::CGFT_ObjectFile; if (TargetMachine->addPassesToEmitFile(pass, dest, FileType)) { cerr << "TargetMachine can't emit a file of this type"; return 1; } pass.run(*TheModule); dest.flush(); delete TheModule; return 0; }