From a6839c548e4c2bb74127ac0a3503b63f78cd2050 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 9 Sep 2020 13:00:06 -0700 Subject: [PATCH] Start using driver, and switch to file IO. --- 13/main.cpp | 19 +++++++++++-------- 13/parse_driver.hpp | 43 +++++++++++++++++++++++++++++++++++++++++++ 13/parser.y | 18 +++++++++++------- 13/scanner.l | 17 +++++++++++++++-- 4 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 13/parse_driver.hpp diff --git a/13/main.cpp b/13/main.cpp index 5ab7ed3..238caea 100644 --- a/13/main.cpp +++ b/13/main.cpp @@ -8,6 +8,7 @@ #include "parser.hpp" #include "error.hpp" #include "type.hpp" +#include "parse_driver.hpp" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Verifier.h" #include "llvm/Support/TargetSelect.h" @@ -21,8 +22,6 @@ void yy::parser::error(const yy::location& loc, const std::string& msg) { std::cout << "An error occured: " << msg << std::endl; } -extern definition_group global_defs; - void typecheck_program( definition_group& defs, type_mgr& mgr, type_env_ptr& env) { @@ -131,13 +130,17 @@ void gen_llvm(global_scope& scope) { output_llvm(ctx, "program.o"); } -int main() { - yy::parser parser; +int main(int argc, char** argv) { + if(argc != 2) { + std::cout << "please enter a file to compile." << std::endl; + } + parse_driver driver(argv[1]); + driver.run_parse(); + type_mgr mgr; type_env_ptr env(new type_env); - parser.parse(); - for(auto& def_defn : global_defs.defs_defn) { + for(auto& def_defn : driver.global_defs.defs_defn) { std::cout << def_defn.second->name; for(auto& param : def_defn.second->params) std::cout << " " << param; std::cout << ":" << std::endl; @@ -145,8 +148,8 @@ int main() { def_defn.second->body->print(1, std::cout); } try { - typecheck_program(global_defs, mgr, env); - global_scope scope = translate_program(global_defs); + typecheck_program(driver.global_defs, mgr, env); + global_scope scope = translate_program(driver.global_defs); scope.compile(); gen_llvm(scope); } catch(unification_error& err) { diff --git a/13/parse_driver.hpp b/13/parse_driver.hpp new file mode 100644 index 0000000..a00c586 --- /dev/null +++ b/13/parse_driver.hpp @@ -0,0 +1,43 @@ +#pragma once +#include +#include +#include "definition.hpp" +#include "location.hh" +#include "parser.hpp" + +struct parse_driver; + +void scanner_init(parse_driver* d, yyscan_t* scanner); +void scanner_destroy(yyscan_t* scanner); + +struct parse_driver { + std::string file_name; + std::ifstream file_stream; + + yy::location location; + size_t file_offset; + + std::vector line_offsets; + definition_group global_defs; + + parse_driver(const std::string& file) + : file_name(file) {} + + void run_parse() { + file_stream.open(file_name); + if(!file_stream.good()) throw 0; + yyscan_t scanner; + scanner_init(this, &scanner); + yy::parser parser(scanner, *this); + parser(); + scanner_destroy(&scanner); + } + + int get() { + return file_stream.get(); + } +}; + +#define YY_DECL yy::parser::symbol_type yylex(yyscan_t yyscanner, parse_driver& drv) + +YY_DECL; diff --git a/13/parser.y b/13/parser.y index c4edbb3..3fefb28 100644 --- a/13/parser.y +++ b/13/parser.y @@ -1,17 +1,21 @@ -%{ +%code requires { #include -#include -#include +#include #include "ast.hpp" #include "definition.hpp" #include "parser.hpp" #include "parsed_type.hpp" -definition_group global_defs; +class parse_driver; +using yyscan_t = void*; +} -extern yy::parser::symbol_type yylex(); +%param { yyscan_t scanner } +%param { parse_driver& drv } -%} +%code { +#include "parse_driver.hpp" +} %token BACKSLASH %token PLUS @@ -59,7 +63,7 @@ extern yy::parser::symbol_type yylex(); %% program - : definitions { global_defs = std::move($1); global_defs.vis = visibility::global; } + : definitions { $1.vis = visibility::global; std::swap(drv.global_defs, $1); } ; definitions diff --git a/13/scanner.l b/13/scanner.l index c571910..e409014 100644 --- a/13/scanner.l +++ b/13/scanner.l @@ -1,16 +1,22 @@ %option noyywrap +%option reentrant %{ #include #include "ast.hpp" #include "definition.hpp" +#include "parse_driver.hpp" #include "parser.hpp" yy::parser::location_type location; -#define YY_DECL yy::parser::symbol_type yylex() +#define YY_EXTRA_TYPE parse_driver* #define YY_USER_ACTION location.step(); location.columns(yyleng); - +#define YY_INPUT(buf,result,max_size) \ + { \ + int c = yyextra->get(); \ + result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \ + } %} %% @@ -41,3 +47,10 @@ in { return yy::parser::make_IN(location); } <> { return yy::parser::make_YYEOF(location); } %% + +void scanner_init(parse_driver* d, yyscan_t* scanner) { + yylex_init_extra(d, scanner); +} +void scanner_destroy(yyscan_t* scanner) { + yylex_destroy(*scanner); +}