diff --git a/code/compiler/13/ast.cpp b/code/compiler/13/ast.cpp index 57293e9..5153fa4 100644 --- a/code/compiler/13/ast.cpp +++ b/code/compiler/13/ast.cpp @@ -212,6 +212,10 @@ type_ptr ast_case::typecheck(type_mgr& mgr, type_env_ptr& env) { input_type = mgr.resolve(case_type, var); type_app* app_type; + if(!(app_type = dynamic_cast(input_type.get())) || + !dynamic_cast(app_type->constructor.get())) { + throw type_error("attempting case analysis of non-data type"); + } return branch_type; } @@ -223,219 +227,60 @@ void ast_case::translate(global_scope& scope) { } } -template -struct case_mappings { - using tag_type = typename T::tag_type; - std::map> defined_cases; - std::optional> default_case; - - std::vector& make_case_for(tag_type tag) { - if(default_case) - throw compiler_error("attempted pattern match after catch-all"); - return defined_cases[tag]; - } - - std::vector& make_default_case() { - if(default_case) - throw compiler_error("attempted repeated use of catch-all"); - default_case.emplace(std::vector()); - return *default_case; - } - - std::vector& get_specific_case_for(tag_type tag) { - auto existing_case = defined_cases.find(tag); - assert(existing_case != defined_cases.end()); - return existing_case->second; - } - - std::vector& get_default_case() { - assert(default_case); - return *default_case; - } - - std::vector& get_case_for(tag_type tag) { - if(case_defined_for(tag)) return get_specific_case_for(tag); - return get_default_case(); - } - - bool case_defined_for(tag_type tag) { - return defined_cases.find(tag) != defined_cases.end(); - } - - bool default_case_defined() { return default_case.has_value(); } - - size_t defined_cases_count() { return defined_cases.size(); } -}; - - -struct case_strategy_bool { - using tag_type = bool; - using repr_type = bool; - - case_strategy_bool(const type* type) {} - - tag_type tag_from_repr(repr_type b) { return b; } - - repr_type repr_from_pattern(const pattern_ptr& pt) { - pattern_constr* cpat; - if(!(cpat = dynamic_cast(pt.get())) || - (cpat->constr != "True" && cpat->constr != "False") || - cpat->params.size() != 0) - throw compiler_error( - "pattern cannot be converted to a boolean", - pt->loc); - return cpat->constr == "True"; - } - - void compile_branch( - const branch_ptr& branch, - const env_ptr& env, - repr_type repr, - std::vector& into) { - branch->expr->compile(env_ptr(new env_offset(1, env)), into); - into.push_back(instruction_ptr(new instruction_slide(1))); - } - - size_t case_count() { - return 2; - } - - void into_instructions( - case_mappings& ms, - std::vector& into) { - if(ms.defined_cases_count() == 0) { - for(auto& instruction : ms.get_default_case()) - into.push_back(std::move(instruction)); - return; - } - - instruction_ijump* ijump = new instruction_ijump(); - instruction_ptr inst(ijump); - ijump->branches.push_back(std::move(ms.get_case_for(false))); - ijump->tag_mappings[0] = 0; - ijump->branches.push_back(std::move(ms.get_case_for(true))); - ijump->tag_mappings[1] = 1; - into.push_back(std::move(inst)); - } -}; - -struct case_strategy_data { - using tag_type = int; - using repr_type = std::pair*>; - - const type_data* arg_type; - - case_strategy_data(const type* t) { - arg_type = dynamic_cast(t); - assert(arg_type); - } - - tag_type tag_from_repr(const repr_type& repr) { return repr.first->tag; } - - repr_type repr_from_pattern(const pattern_ptr& pt) { - pattern_constr* cpat; - if(!(cpat = dynamic_cast(pt.get()))) - throw compiler_error( - "pattern cannot be interpreted as constructor.", - pt->loc); - return std::make_pair( - &arg_type->constructors.find(cpat->constr)->second, - &cpat->params); - } - - void compile_branch( - const branch_ptr& branch, - const env_ptr& env, - const repr_type& repr, - std::vector& into) { - env_ptr new_env = env; - for(auto it = repr.second->rbegin(); it != repr.second->rend(); it++) { - new_env = env_ptr(new env_var(*it, new_env)); - } - - into.push_back(instruction_ptr(new instruction_split(repr.second->size()))); - branch->expr->compile(new_env, into); - into.push_back(instruction_ptr(new instruction_slide(repr.second->size()))); - } - - size_t case_count() { - return arg_type->constructors.size(); - } - - void into_instructions( - case_mappings& ms, - std::vector& into) { - instruction_jump* jump_instruction = new instruction_jump(); - instruction_ptr inst(jump_instruction); - - for(auto& constr : arg_type->constructors) { - if(!ms.case_defined_for(constr.second.tag)) continue; - jump_instruction->branches.push_back( - std::move(ms.get_specific_case_for(constr.second.tag))); - jump_instruction->tag_mappings[constr.second.tag] = - jump_instruction->branches.size() - 1; - } - - if(ms.default_case_defined()) { - jump_instruction->branches.push_back( - std::move(ms.get_default_case())); - for(auto& constr : arg_type->constructors) { - if(ms.case_defined_for(constr.second.tag)) continue; - jump_instruction->tag_mappings[constr.second.tag] = - jump_instruction->branches.size(); - } - } - - into.push_back(std::move(inst)); - } -}; - -template -void compile_case(const ast_case& node, const env_ptr& env, const type* type, std::vector& into) { - T strategy(type); - case_mappings cases; - for(auto& branch : node.branches) { - pattern_var* vpat; - if((vpat = dynamic_cast(branch->pat.get()))) { - if(cases.defined_cases_count() == strategy.case_count()) - throw compiler_error("redundant catch-all pattern", branch->pat->loc); - auto& branch_into = cases.make_default_case(); - env_ptr new_env(new env_var(vpat->var, env)); - branch->expr->compile(new_env, branch_into); - branch_into.push_back(instruction_ptr(new instruction_slide(1))); - } else { - auto repr = strategy.repr_from_pattern(branch->pat); - auto& branch_into = cases.make_case_for(strategy.tag_from_repr(repr)); - strategy.compile_branch(branch, env, repr, branch_into); - } - } - - if(!(cases.defined_cases_count() == strategy.case_count() || - cases.default_case_defined())) - throw compiler_error("incomplete patterns", node.loc); - - strategy.into_instructions(cases, into); -} - void ast_case::compile(const env_ptr& env, std::vector& into) const { type_app* app_type = dynamic_cast(input_type.get()); - type_data* data; - type_base *base; + type_data* type = dynamic_cast(app_type->constructor.get()); of->compile(env, into); into.push_back(instruction_ptr(new instruction_eval())); - if(app_type && (data = dynamic_cast(app_type->constructor.get()))) { - compile_case(*this, env, data, into); - return; - } else if (app_type && (base = dynamic_cast(app_type->constructor.get()))) { - if (base->name == "Bool") { - compile_case(*this, env, data, into); - return; - } + instruction_jump* jump_instruction = new instruction_jump(); + into.push_back(instruction_ptr(jump_instruction)); + for(auto& branch : branches) { + std::vector branch_instructions; + pattern_var* vpat; + pattern_constr* cpat; + + if((vpat = dynamic_cast(branch->pat.get()))) { + branch->expr->compile(env_ptr(new env_offset(1, env)), branch_instructions); + + for(auto& constr_pair : type->constructors) { + if(jump_instruction->tag_mappings.find(constr_pair.second.tag) != + jump_instruction->tag_mappings.end()) + break; + + jump_instruction->tag_mappings[constr_pair.second.tag] = + jump_instruction->branches.size(); + } + jump_instruction->branches.push_back(std::move(branch_instructions)); + } else if((cpat = dynamic_cast(branch->pat.get()))) { + env_ptr new_env = env; + for(auto it = cpat->params.rbegin(); it != cpat->params.rend(); it++) { + new_env = env_ptr(new env_var(*it, new_env)); + } + + branch_instructions.push_back(instruction_ptr(new instruction_split( + cpat->params.size()))); + branch->expr->compile(new_env, branch_instructions); + branch_instructions.push_back(instruction_ptr(new instruction_slide( + cpat->params.size()))); + + int new_tag = type->constructors[cpat->constr].tag; + if(jump_instruction->tag_mappings.find(new_tag) != + jump_instruction->tag_mappings.end()) + throw type_error("technically not a type error: duplicate pattern"); + + jump_instruction->tag_mappings[new_tag] = + jump_instruction->branches.size(); + jump_instruction->branches.push_back(std::move(branch_instructions)); + } } - throw type_error("attempting unsupported case analysis", of->loc); + for(auto& constr_pair : type->constructors) { + if(jump_instruction->tag_mappings.find(constr_pair.second.tag) == + jump_instruction->tag_mappings.end()) + throw type_error("non-total pattern"); + } } void ast_let::print(int indent, std::ostream& to) const { diff --git a/code/compiler/13/binop.cpp b/code/compiler/13/binop.cpp index f311007..3a5f0ca 100644 --- a/code/compiler/13/binop.cpp +++ b/code/compiler/13/binop.cpp @@ -6,9 +6,6 @@ std::string op_name(binop op) { case MINUS: return "-"; case TIMES: return "*"; case DIVIDE: return "/"; - case MODULO: return "%"; - case EQUALS: return "=="; - case LESS_EQUALS: return "<="; } return "??"; } @@ -19,9 +16,6 @@ std::string op_action(binop op) { case MINUS: return "minus"; case TIMES: return "times"; case DIVIDE: return "divide"; - case MODULO: return "modulo"; - case EQUALS: return "equals"; - case LESS_EQUALS: return "less_equals"; } return "??"; } diff --git a/code/compiler/13/binop.hpp b/code/compiler/13/binop.hpp index 1a74323..d8b44d7 100644 --- a/code/compiler/13/binop.hpp +++ b/code/compiler/13/binop.hpp @@ -6,15 +6,11 @@ enum binop { PLUS, MINUS, TIMES, - DIVIDE, - MODULO, - EQUALS, - LESS_EQUALS, + DIVIDE }; constexpr binop all_binops[] = { - PLUS, MINUS, TIMES, DIVIDE, MODULO, - EQUALS, LESS_EQUALS + PLUS, MINUS, TIMES, DIVIDE }; std::string op_name(binop op); diff --git a/code/compiler/13/compiler.cpp b/code/compiler/13/compiler.cpp index be06d10..b1c978b 100644 --- a/code/compiler/13/compiler.cpp +++ b/code/compiler/13/compiler.cpp @@ -17,7 +17,6 @@ void compiler::add_default_types() { global_env->bind_type("Int", type_ptr(new type_base("Int"))); - global_env->bind_type("Bool", type_ptr(new type_base("Bool"))); } void compiler::add_binop_type(binop op, type_ptr type) { @@ -31,24 +30,11 @@ void compiler::add_default_function_types() { assert(int_type != nullptr); type_ptr int_type_app = type_ptr(new type_app(int_type)); - type_ptr bool_type = global_env->lookup_type("Bool"); - assert(bool_type != nullptr); - type_ptr bool_type_app = type_ptr(new type_app(bool_type)); - type_ptr closed_int_op_type( new type_arr(int_type_app, type_ptr(new type_arr(int_type_app, int_type_app)))); - type_ptr compare_int_op_type( - new type_arr(int_type_app, type_ptr(new type_arr(int_type_app, bool_type_app)))); - constexpr binop closed_ops[] = { PLUS, MINUS, TIMES, DIVIDE, MODULO }; - constexpr binop compare_ops[] = { EQUALS, LESS_EQUALS }; + constexpr binop closed_ops[] = { PLUS, MINUS, TIMES, DIVIDE }; for(auto& op : closed_ops) add_binop_type(op, closed_int_op_type); - for(auto& op : compare_ops) add_binop_type(op, compare_int_op_type); - - for(auto name : { "True", "False" }) { - global_env->bind(name, bool_type_app, visibility::global); - global_env->set_mangled_name(name, mng.new_mangled_name(name)); - } } void compiler::parse() { @@ -94,25 +80,10 @@ void compiler::create_llvm_binop(binop op) { ctx.get_builder().CreateRetVoid(); } -void compiler::create_llvm_bool(bool b) { - auto new_function = ctx.create_custom_function( - global_env->get_mangled_name(b ? "True" : "False"), 0); - std::vector instructions; - instructions.push_back(instruction_ptr(new instruction_pushint(b))); - instructions.push_back(instruction_ptr(new instruction_update(0))); - ctx.get_builder().SetInsertPoint(&new_function->getEntryBlock()); - for(auto& instruction : instructions) { - instruction->gen_llvm(ctx, new_function); - } - ctx.get_builder().CreateRetVoid(); -} - void compiler::generate_llvm() { for(auto op : all_binops) { create_llvm_binop(op); } - create_llvm_bool(true); - create_llvm_bool(false); global_scp.generate_llvm(ctx); } diff --git a/code/compiler/13/compiler.hpp b/code/compiler/13/compiler.hpp index f26d5d6..df379ca 100644 --- a/code/compiler/13/compiler.hpp +++ b/code/compiler/13/compiler.hpp @@ -27,7 +27,6 @@ class compiler { void translate(); void compile(); void create_llvm_binop(binop op); - void create_llvm_bool(bool b); void generate_llvm(); void output_llvm(const std::string& into); public: diff --git a/code/compiler/13/instruction.cpp b/code/compiler/13/instruction.cpp index 4700688..b3fff15 100644 --- a/code/compiler/13/instruction.cpp +++ b/code/compiler/13/instruction.cpp @@ -100,7 +100,7 @@ void instruction_jump::print(int indent, std::ostream& to) const { void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const { auto top_node = ctx.create_peek(f, ctx.create_size(0)); - auto tag = get_case_value(ctx, top_node); + auto tag = ctx.unwrap_data_tag(top_node); auto safety_block = ctx.create_basic_block("safety", f); auto switch_op = ctx.get_builder().CreateSwitch(tag, safety_block, tag_mappings.size()); std::vector blocks; @@ -122,14 +122,6 @@ void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const { ctx.get_builder().SetInsertPoint(safety_block); } -Value* instruction_jump::get_case_value(llvm_context& ctx, Value* v) const { - return ctx.unwrap_data_tag(v); -} - -Value* instruction_ijump::get_case_value(llvm_context& ctx, Value* v) const { - return ctx.unwrap_num(v); -} - void instruction_slide::print(int indent, std::ostream& to) const { print_indent(indent, to); to << "Slide(" << offset << ")" << std::endl; @@ -153,9 +145,6 @@ void instruction_binop::gen_llvm(llvm_context& ctx, Function* f) const { case MINUS: result = ctx.get_builder().CreateSub(left_int, right_int); break; case TIMES: result = ctx.get_builder().CreateMul(left_int, right_int); break; case DIVIDE: result = ctx.get_builder().CreateSDiv(left_int, right_int); break; - case MODULO: result = ctx.get_builder().CreateSRem(left_int, right_int); break; - case EQUALS: result = ctx.get_builder().CreateICmpEQ(left_int, right_int); break; - case LESS_EQUALS: result = ctx.get_builder().CreateICmpSLE(left_int, right_int); break; } ctx.create_push(f, ctx.create_num(f, result)); } diff --git a/code/compiler/13/instruction.hpp b/code/compiler/13/instruction.hpp index 15639ed..abe2409 100644 --- a/code/compiler/13/instruction.hpp +++ b/code/compiler/13/instruction.hpp @@ -99,12 +99,6 @@ struct instruction_jump : public instruction { void print(int indent, std::ostream& to) const; void gen_llvm(llvm_context& ctx, llvm::Function* f) const; - - virtual llvm::Value* get_case_value(llvm_context& ctx, llvm::Value*) const; -}; - -struct instruction_ijump : public instruction_jump { - llvm::Value* get_case_value(llvm_context& ctx, llvm::Value*) const; }; struct instruction_slide : public instruction { diff --git a/code/compiler/13/llvm_context.cpp b/code/compiler/13/llvm_context.cpp index 75f62a4..8d9fb1f 100644 --- a/code/compiler/13/llvm_context.cpp +++ b/code/compiler/13/llvm_context.cpp @@ -237,7 +237,12 @@ Value* llvm_context::unwrap_gmachine_stack_ptr(Value* g) { } Value* llvm_context::unwrap_num(Value* v) { - return builder.CreatePtrToInt(v, IntegerType::getInt32Ty(ctx)); + auto num_ptr_type = PointerType::getUnqual(struct_types.at("node_num")); + auto cast = builder.CreatePointerCast(v, num_ptr_type); + auto offset_0 = create_i32(0); + auto offset_1 = create_i32(1); + auto int_ptr = builder.CreateGEP(cast, { offset_0, offset_1 }); + return builder.CreateLoad(int_ptr); } Value* llvm_context::create_num(Function* f, Value* v) { auto alloc_num_f = functions.at("alloc_num"); diff --git a/code/compiler/13/parser.y b/code/compiler/13/parser.y index 0791f76..86740cd 100644 --- a/code/compiler/13/parser.y +++ b/code/compiler/13/parser.y @@ -18,14 +18,10 @@ using yyscan_t = void*; } %token BACKSLASH -%token BACKTICK %token PLUS %token TIMES %token MINUS %token DIVIDE -%token MODULO -%token EQUALS -%token LESS_EQUALS %token INT %token DEFN %token DATA @@ -53,10 +49,9 @@ using yyscan_t = void*; %type > branches %type > constructors %type > typeList -%type anyBinop %type definitions %type type nonArrowType typeListElement -%type aInfix aEq aAdd aMul case let lambda app appBase +%type aAdd aMul case let lambda app appBase %type data %type defn %type branch @@ -78,7 +73,7 @@ definitions ; defn - : DEFN LID lowercaseParams EQUAL OCURLY aInfix CCURLY + : DEFN LID lowercaseParams EQUAL OCURLY aAdd CCURLY { $$ = definition_defn_ptr( new definition_defn(std::move($2), std::move($3), std::move($6), @$)); } ; @@ -88,22 +83,6 @@ lowercaseParams | lowercaseParams LID { $$ = std::move($1); $$.push_back(std::move($2)); } ; -aInfix - : aInfix BACKTICK LID BACKTICK aEq - { $$ = ast_ptr(new ast_app( - ast_ptr(new ast_app(ast_ptr(new ast_lid(std::move($3))), std::move($1))), std::move($5))); } - | aInfix BACKTICK UID BACKTICK aEq - { $$ = ast_ptr(new ast_app( - ast_ptr(new ast_app(ast_ptr(new ast_uid(std::move($3))), std::move($1))), std::move($5))); } - | aEq { $$ = std::move($1); } - ; - -aEq - : aAdd EQUALS aAdd { $$ = ast_ptr(new ast_binop(EQUALS, std::move($1), std::move($3), @$)); } - | aAdd LESS_EQUALS aAdd { $$ = ast_ptr(new ast_binop(LESS_EQUALS, std::move($1), std::move($3), @$)); } - | aAdd { $$ = std::move($1); } - ; - aAdd : aAdd PLUS aMul { $$ = ast_ptr(new ast_binop(PLUS, std::move($1), std::move($3), @$)); } | aAdd MINUS aMul { $$ = ast_ptr(new ast_binop(MINUS, std::move($1), std::move($3), @$)); } @@ -113,7 +92,6 @@ aAdd aMul : aMul TIMES app { $$ = ast_ptr(new ast_binop(TIMES, std::move($1), std::move($3), @$)); } | aMul DIVIDE app { $$ = ast_ptr(new ast_binop(DIVIDE, std::move($1), std::move($3), @$)); } - | aMul MODULO app { $$ = ast_ptr(new ast_binop(MODULO, std::move($1), std::move($3), @$)); } | app { $$ = std::move($1); } ; @@ -126,35 +104,24 @@ appBase : INT { $$ = ast_ptr(new ast_int($1, @$)); } | LID { $$ = ast_ptr(new ast_lid(std::move($1), @$)); } | UID { $$ = ast_ptr(new ast_uid(std::move($1), @$)); } - | OPAREN aInfix CPAREN { $$ = std::move($2); } - | OPAREN anyBinop CPAREN { $$ = ast_ptr(new ast_lid(op_name($2))); } + | OPAREN aAdd CPAREN { $$ = std::move($2); } | case { $$ = std::move($1); } | let { $$ = std::move($1); } | lambda { $$ = std::move($1); } ; -anyBinop - : PLUS { $$ = PLUS; } - | MINUS { $$ = MINUS; } - | TIMES { $$ = TIMES; } - | DIVIDE { $$ = DIVIDE; } - | MODULO { $$ = MODULO; } - | EQUALS { $$ = EQUALS; } - | LESS_EQUALS { $$ = LESS_EQUALS; } - ; - let - : LET OCURLY definitions CCURLY IN OCURLY aInfix CCURLY + : LET OCURLY definitions CCURLY IN OCURLY aAdd CCURLY { $$ = ast_ptr(new ast_let(std::move($3), std::move($7), @$)); } ; lambda - : BACKSLASH lowercaseParams ARROW OCURLY aInfix CCURLY + : BACKSLASH lowercaseParams ARROW OCURLY aAdd CCURLY { $$ = ast_ptr(new ast_lambda(std::move($2), std::move($5), @$)); } ; case - : CASE aInfix OF OCURLY branches CCURLY + : CASE aAdd OF OCURLY branches CCURLY { $$ = ast_ptr(new ast_case(std::move($2), std::move($5), @$)); } ; @@ -164,7 +131,7 @@ branches ; branch - : pattern ARROW OCURLY aInfix CCURLY + : pattern ARROW OCURLY aAdd CCURLY { $$ = branch_ptr(new branch(std::move($1), std::move($4))); } ; diff --git a/code/compiler/13/runtime.c b/code/compiler/13/runtime.c index 8e2daf3..7b8a7c3 100644 --- a/code/compiler/13/runtime.c +++ b/code/compiler/13/runtime.c @@ -1,13 +1,9 @@ -#include #include #include #include #include #include "runtime.h" -#define TOGGLE_MARK(n) ((uint64_t) n ^ ((uint64_t) 1 << 63)) -#define IS_MARKED(n) ((((uint64_t) n) ^ ((uint64_t) n << 1)) & ((uint64_t) 1 << 63)) - struct node_base* alloc_node() { struct node_base* new_node = malloc(sizeof(struct node_app)); new_node->gc_next = NULL; @@ -25,7 +21,10 @@ struct node_app* alloc_app(struct node_base* l, struct node_base* r) { } struct node_num* alloc_num(int32_t n) { - return (struct node_num*) TOGGLE_MARK(n); + struct node_num* node = (struct node_num*) alloc_node(); + node->base.tag = NODE_NUM; + node->value = n; + return node; } struct node_global* alloc_global(void (*f)(struct gmachine*), int32_t a) { @@ -50,7 +49,7 @@ void free_node_direct(struct node_base* n) { } void gc_visit_node(struct node_base* n) { - if(IS_MARKED(n) || n->gc_reachable) return; + if(n->gc_reachable) return; n->gc_reachable = 1; if(n->tag == NODE_APP) { @@ -170,7 +169,6 @@ void gmachine_split(struct gmachine* g, size_t n) { } struct node_base* gmachine_track(struct gmachine* g, struct node_base* b) { - if(IS_MARKED(b)) return b; g->gc_node_count++; b->gc_next = g->gc_nodes; g->gc_nodes = b; @@ -210,9 +208,7 @@ void unwind(struct gmachine* g) { while(1) { struct node_base* peek = stack_peek(s, 0); - if(IS_MARKED(peek)) { - break; - } else if(peek->tag == NODE_APP) { + if(peek->tag == NODE_APP) { struct node_app* n = (struct node_app*) peek; stack_push(s, n->left); } else if(peek->tag == NODE_GLOBAL) { @@ -238,9 +234,7 @@ void unwind(struct gmachine* g) { extern void f_main(struct gmachine* s); void print_node(struct node_base* n) { - if(IS_MARKED(n)) { - printf("%d", (int32_t) n); - } else if(n->tag == NODE_APP) { + if(n->tag == NODE_APP) { struct node_app* app = (struct node_app*) n; print_node(app->left); putchar(' '); @@ -252,6 +246,9 @@ void print_node(struct node_base* n) { printf("(Global: %p)", global->function); } else if(n->tag == NODE_IND) { print_node(((struct node_ind*) n)->next); + } else if(n->tag == NODE_NUM) { + struct node_num* num = (struct node_num*) n; + printf("%d", num->value); } } diff --git a/code/compiler/13/scanner.hpp b/code/compiler/13/scanner.hpp deleted file mode 100644 index 383b6d6..0000000 --- a/code/compiler/13/scanner.hpp +++ /dev/null @@ -1,492 +0,0 @@ -#ifndef yyHEADER_H -#define yyHEADER_H 1 -#define yyIN_HEADER 1 - -#line 5 "scanner.hpp" - -#line 7 "scanner.hpp" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 6 -#define YY_FLEX_SUBMINOR_VERSION 4 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#ifndef SIZE_MAX -#define SIZE_MAX (~(size_t)0) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -/* begin standard C++ headers. */ - -/* TODO: this is always defined, so inline it */ -#define yyconst const - -#if defined(__GNUC__) && __GNUC__ >= 3 -#define yynoreturn __attribute__((__noreturn__)) -#else -#define yynoreturn -#endif - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - int yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -void yyrestart ( FILE *input_file , yyscan_t yyscanner ); -void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); -YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); -void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); -void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); -void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); -void yypop_buffer_state ( yyscan_t yyscanner ); - -YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); - -void *yyalloc ( yy_size_t , yyscan_t yyscanner ); -void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); -void yyfree ( void * , yyscan_t yyscanner ); - -/* Begin user sect3 */ - -#define yywrap(yyscanner) (/*CONSTCOND*/1) -#define YY_SKIP_YYWRAP - -#define yytext_ptr yytext_r - -#ifdef YY_HEADER_EXPORT_START_CONDITIONS -#define INITIAL 0 - -#endif - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -int yylex_init (yyscan_t* scanner); - -int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy ( yyscan_t yyscanner ); - -int yyget_debug ( yyscan_t yyscanner ); - -void yyset_debug ( int debug_flag , yyscan_t yyscanner ); - -YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); - -void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); - -FILE *yyget_in ( yyscan_t yyscanner ); - -void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); - -FILE *yyget_out ( yyscan_t yyscanner ); - -void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); - - int yyget_leng ( yyscan_t yyscanner ); - -char *yyget_text ( yyscan_t yyscanner ); - -int yyget_lineno ( yyscan_t yyscanner ); - -void yyset_lineno ( int _line_number , yyscan_t yyscanner ); - -int yyget_column ( yyscan_t yyscanner ); - -void yyset_column ( int _column_no , yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap ( yyscan_t yyscanner ); -#else -extern int yywrap ( yyscan_t yyscanner ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen ( const char * , yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex (yyscan_t yyscanner); - -#define YY_DECL int yylex (yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -#undef YY_NEW_FILE -#undef YY_FLUSH_BUFFER -#undef yy_set_bol -#undef yy_new_buffer -#undef yy_set_interactive -#undef YY_DO_BEFORE_ACTION - -#ifdef YY_DECL_IS_OURS -#undef YY_DECL_IS_OURS -#undef YY_DECL -#endif - -#ifndef yy_create_buffer_ALREADY_DEFINED -#undef yy_create_buffer -#endif -#ifndef yy_delete_buffer_ALREADY_DEFINED -#undef yy_delete_buffer -#endif -#ifndef yy_scan_buffer_ALREADY_DEFINED -#undef yy_scan_buffer -#endif -#ifndef yy_scan_string_ALREADY_DEFINED -#undef yy_scan_string -#endif -#ifndef yy_scan_bytes_ALREADY_DEFINED -#undef yy_scan_bytes -#endif -#ifndef yy_init_buffer_ALREADY_DEFINED -#undef yy_init_buffer -#endif -#ifndef yy_flush_buffer_ALREADY_DEFINED -#undef yy_flush_buffer -#endif -#ifndef yy_load_buffer_state_ALREADY_DEFINED -#undef yy_load_buffer_state -#endif -#ifndef yy_switch_to_buffer_ALREADY_DEFINED -#undef yy_switch_to_buffer -#endif -#ifndef yypush_buffer_state_ALREADY_DEFINED -#undef yypush_buffer_state -#endif -#ifndef yypop_buffer_state_ALREADY_DEFINED -#undef yypop_buffer_state -#endif -#ifndef yyensure_buffer_stack_ALREADY_DEFINED -#undef yyensure_buffer_stack -#endif -#ifndef yylex_ALREADY_DEFINED -#undef yylex -#endif -#ifndef yyrestart_ALREADY_DEFINED -#undef yyrestart -#endif -#ifndef yylex_init_ALREADY_DEFINED -#undef yylex_init -#endif -#ifndef yylex_init_extra_ALREADY_DEFINED -#undef yylex_init_extra -#endif -#ifndef yylex_destroy_ALREADY_DEFINED -#undef yylex_destroy -#endif -#ifndef yyget_debug_ALREADY_DEFINED -#undef yyget_debug -#endif -#ifndef yyset_debug_ALREADY_DEFINED -#undef yyset_debug -#endif -#ifndef yyget_extra_ALREADY_DEFINED -#undef yyget_extra -#endif -#ifndef yyset_extra_ALREADY_DEFINED -#undef yyset_extra -#endif -#ifndef yyget_in_ALREADY_DEFINED -#undef yyget_in -#endif -#ifndef yyset_in_ALREADY_DEFINED -#undef yyset_in -#endif -#ifndef yyget_out_ALREADY_DEFINED -#undef yyget_out -#endif -#ifndef yyset_out_ALREADY_DEFINED -#undef yyset_out -#endif -#ifndef yyget_leng_ALREADY_DEFINED -#undef yyget_leng -#endif -#ifndef yyget_text_ALREADY_DEFINED -#undef yyget_text -#endif -#ifndef yyget_lineno_ALREADY_DEFINED -#undef yyget_lineno -#endif -#ifndef yyset_lineno_ALREADY_DEFINED -#undef yyset_lineno -#endif -#ifndef yyget_column_ALREADY_DEFINED -#undef yyget_column -#endif -#ifndef yyset_column_ALREADY_DEFINED -#undef yyset_column -#endif -#ifndef yywrap_ALREADY_DEFINED -#undef yywrap -#endif -#ifndef yyget_lval_ALREADY_DEFINED -#undef yyget_lval -#endif -#ifndef yyset_lval_ALREADY_DEFINED -#undef yyset_lval -#endif -#ifndef yyget_lloc_ALREADY_DEFINED -#undef yyget_lloc -#endif -#ifndef yyset_lloc_ALREADY_DEFINED -#undef yyset_lloc -#endif -#ifndef yyalloc_ALREADY_DEFINED -#undef yyalloc -#endif -#ifndef yyrealloc_ALREADY_DEFINED -#undef yyrealloc -#endif -#ifndef yyfree_ALREADY_DEFINED -#undef yyfree -#endif -#ifndef yytext_ALREADY_DEFINED -#undef yytext -#endif -#ifndef yyleng_ALREADY_DEFINED -#undef yyleng -#endif -#ifndef yyin_ALREADY_DEFINED -#undef yyin -#endif -#ifndef yyout_ALREADY_DEFINED -#undef yyout -#endif -#ifndef yy_flex_debug_ALREADY_DEFINED -#undef yy_flex_debug -#endif -#ifndef yylineno_ALREADY_DEFINED -#undef yylineno -#endif -#ifndef yytables_fload_ALREADY_DEFINED -#undef yytables_fload -#endif -#ifndef yytables_destroy_ALREADY_DEFINED -#undef yytables_destroy -#endif -#ifndef yyTABLES_NAME_ALREADY_DEFINED -#undef yyTABLES_NAME -#endif - -#line 49 "/home/vanilla/projects/blog-static/code/compiler/13/scanner.l" - - -#line 490 "scanner.hpp" -#undef yyIN_HEADER -#endif /* yyHEADER_H */ diff --git a/code/compiler/13/scanner.l b/code/compiler/13/scanner.l index 20f9b70..b29987e 100644 --- a/code/compiler/13/scanner.l +++ b/code/compiler/13/scanner.l @@ -24,10 +24,6 @@ \* { return yy::parser::make_TIMES(LOC); } - { return yy::parser::make_MINUS(LOC); } \/ { return yy::parser::make_DIVIDE(LOC); } -% { return yy::parser::make_MODULO(LOC); } -== { return yy::parser::make_EQUALS(LOC); } -\<= { return yy::parser::make_LESS_EQUALS(LOC); } -` { return yy::parser::make_BACKTICK(LOC); } [0-9]+ { return yy::parser::make_INT(atoi(yytext), LOC); } defn { return yy::parser::make_DEFN(LOC); } data { return yy::parser::make_DATA(LOC); } diff --git a/code/compiler/13/type.cpp b/code/compiler/13/type.cpp index fb3ab68..c604580 100644 --- a/code/compiler/13/type.cpp +++ b/code/compiler/13/type.cpp @@ -38,10 +38,6 @@ void type_base::print(const type_mgr& mgr, std::ostream& to) const { to << name; } -void type_internal::print(const type_mgr& mgr, std::ostream& to) const { - to << "!" << name; -} - void type_arr::print(const type_mgr& mgr, std::ostream& to) const { type_var* var; bool print_parenths = dynamic_cast(mgr.resolve(left, var).get()) != nullptr; @@ -128,8 +124,7 @@ void type_mgr::unify(type_ptr l, type_ptr r, const std::optional& } else if((lid = dynamic_cast(l.get())) && (rid = dynamic_cast(r.get()))) { if(lid->name == rid->name && - lid->arity == rid->arity && - lid->is_internal() == rid->is_internal()) + lid->arity == rid->arity) return; } else if((lapp = dynamic_cast(l.get())) && (rapp = dynamic_cast(r.get()))) { diff --git a/code/compiler/13/type.hpp b/code/compiler/13/type.hpp index cb1d77e..ada3405 100644 --- a/code/compiler/13/type.hpp +++ b/code/compiler/13/type.hpp @@ -46,17 +46,6 @@ struct type_base : public type { : name(std::move(n)), arity(a) {} void print(const type_mgr& mgr, std::ostream& to) const; - - virtual bool is_internal() const { return false; } -}; - -struct type_internal : public type_base { - type_internal(std::string n, int32_t a = 0) - : type_base(std::move(n), a) {} - - void print(const type_mgr& mgr, std::ostream& to) const; - - bool is_internal() const { return true; } }; struct type_data : public type_base {