Start working on types.
This commit is contained in:
parent
7bd6913ac5
commit
1be78c3548
12
src/data.hpp
Normal file
12
src/data.hpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "type.hpp"
|
||||
|
||||
namespace lily {
|
||||
struct constructor {
|
||||
int parent_type;
|
||||
int tag;
|
||||
std::vector<type_ptr> params;
|
||||
};
|
||||
}
|
|
@ -4,7 +4,11 @@
|
|||
|
||||
int main() {
|
||||
try {
|
||||
lily::parse("defn add x y = { x + y }");
|
||||
lily::parse(
|
||||
"data Bool = { True, False }\n"
|
||||
"data Color = { Red, Black }\n"
|
||||
"data IntList = { Nil, Cons(Int, Int) }\n"
|
||||
"defn add x y = { x + y }");
|
||||
} catch(lily::error& e) {
|
||||
std::cout << e.message << std::endl;
|
||||
}
|
||||
|
|
|
@ -146,9 +146,9 @@ namespace lily {
|
|||
if(PGS_TREE_NT_COUNT(*def) == 5) {
|
||||
pgs_tree* params = PGS_TREE_NT_CHILD(*def, 2);
|
||||
do {
|
||||
pgs_tree* param = PGS_TREE_NT_CHILD(*def, 0);
|
||||
pgs_tree* param = PGS_TREE_NT_CHILD(*params, 0);
|
||||
params =
|
||||
(PGS_TREE_NT_COUNT(*def) == 2) ? PGS_TREE_NT_CHILD(*def, 1) : nullptr;
|
||||
(PGS_TREE_NT_COUNT(*params) == 2) ? PGS_TREE_NT_CHILD(*params, 1) : nullptr;
|
||||
|
||||
size_t from = PGS_TREE_T_FROM(*param);
|
||||
size_t to = PGS_TREE_T_TO(*param);
|
||||
|
@ -160,16 +160,62 @@ namespace lily {
|
|||
}
|
||||
}
|
||||
|
||||
static type_ptr type_tree(program& prog, pgs_tree* type, const char* source) {
|
||||
std::string str = tree_str(PGS_TREE_NT_CHILD(*type, 0), source);
|
||||
if(!prog.types.count(str)) throw error("unknown type");
|
||||
|
||||
return prog.types[str];
|
||||
}
|
||||
|
||||
static void collect_type_params(program& prog, std::vector<type_ptr>& into, pgs_tree* params, const char* source) {
|
||||
while(true) {
|
||||
pgs_tree* param = PGS_TREE_NT_CHILD(*params, 0);
|
||||
into.push_back(type_tree(prog, param, source));
|
||||
|
||||
if(PGS_TREE_NT_COUNT(*params) == 1) break;
|
||||
params = PGS_TREE_NT_CHILD(*params, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void collect_constructors(program& prog, int parent, pgs_tree* def, const char* source) {
|
||||
int id = 0;
|
||||
while(true) {
|
||||
constructor cons;
|
||||
cons.tag = id++;
|
||||
cons.parent_type = parent;
|
||||
|
||||
pgs_tree* elem = PGS_TREE_NT_CHILD(*def, 0);
|
||||
std::string name = tree_str(PGS_TREE_NT_CHILD(*elem, 0), source);
|
||||
if(PGS_TREE_NT_COUNT(*elem) > 1)
|
||||
collect_type_params(prog, cons.params, PGS_TREE_NT_CHILD(*elem, 2), source);
|
||||
prog.constructors[name] = std::move(cons);
|
||||
|
||||
if(PGS_TREE_NT_COUNT(*def) == 1) break;
|
||||
def = PGS_TREE_NT_CHILD(*def, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void add_definition(program& prog, pgs_tree* def, const char* source) {
|
||||
char kw = source[PGS_TREE_T_FROM(*PGS_TREE_NT_CHILD(*def, 0))];
|
||||
if(kw == 'd') {
|
||||
size_t str_from = PGS_TREE_T_FROM(*PGS_TREE_NT_CHILD(*def, 0));
|
||||
if(source[str_from]== 't') {
|
||||
// skip for now
|
||||
} else if(source[str_from + 1] == 'e') {
|
||||
std::string function_name = tree_str(PGS_TREE_NT_CHILD(*def, 1), source);
|
||||
if(prog.functions.count(function_name)) throw error("cannot redefine function");
|
||||
|
||||
function new_function;
|
||||
collect_params(new_function.params, def, source);
|
||||
new_function.body = expr_tree(PGS_TREE_NT_CHILD(*PGS_TREE_NT_CHILD(*def, PGS_TREE_NT_COUNT(*def) - 1), 1), source);
|
||||
} else if(kw == 't') {
|
||||
// skip for now
|
||||
|
||||
prog.functions[function_name] = std::move(new_function);
|
||||
} else {
|
||||
// skip for now
|
||||
std::string data_name = tree_str(PGS_TREE_NT_CHILD(*def, 1), source);
|
||||
if(prog.types.count(data_name)) throw error("cannot redefine type");
|
||||
|
||||
int new_type = prog.next_free_type_id++;
|
||||
collect_constructors(prog, new_type,
|
||||
PGS_TREE_NT_CHILD(*PGS_TREE_NT_CHILD(*def, PGS_TREE_NT_COUNT(*def) - 1), 1), source);
|
||||
prog.types[data_name] = type_ptr(new type_int(new_type));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +226,7 @@ namespace lily {
|
|||
do {
|
||||
pgs_tree* definition = PGS_TREE_NT_CHILD(*program, 0);
|
||||
program =
|
||||
(PGS_TREE_NT_COUNT(*tree) == 2) ? PGS_TREE_NT_CHILD(*tree, 1) : nullptr;
|
||||
(PGS_TREE_NT_COUNT(*program) == 2) ? PGS_TREE_NT_CHILD(*program, 1) : nullptr;
|
||||
|
||||
add_definition(*prog, definition, source);
|
||||
} while(program);
|
||||
|
@ -188,6 +234,31 @@ namespace lily {
|
|||
return prog;
|
||||
}
|
||||
|
||||
static void dump_program(program& prog) {
|
||||
std::cout << "Constructors:" << std::endl;
|
||||
for(auto& pair : prog.constructors) {
|
||||
std::cout << " " << pair.first << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Types:" << std::endl;
|
||||
for(auto& pair : prog.types) {
|
||||
std::cout << " " << pair.first << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Functions:" << std::endl;
|
||||
for(auto& pair : prog.functions) {
|
||||
function& f = pair.second;
|
||||
std::cout << " " << pair.first;
|
||||
for(auto& param : f.params) {
|
||||
std::cout << " " << param;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
program_ptr parse(std::string s) {
|
||||
pgs_state state;
|
||||
pgs_tree* into;
|
||||
|
@ -199,7 +270,14 @@ namespace lily {
|
|||
}
|
||||
|
||||
program_ptr prog = build_program(into, s.c_str());
|
||||
dump_program(*prog);
|
||||
pgs_free_tree(into);
|
||||
return prog;
|
||||
}
|
||||
|
||||
program::program() {
|
||||
types["Int"] = type_ptr(new type_int(type_id_int));
|
||||
types["String"] = type_ptr(new type_int(type_id_str));
|
||||
next_free_type_id = type_id_last;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,17 @@
|
|||
#include "error.hpp"
|
||||
#include "ast.hpp"
|
||||
#include "function.hpp"
|
||||
#include "type.hpp"
|
||||
#include "data.hpp"
|
||||
|
||||
namespace lily {
|
||||
struct program {
|
||||
int next_free_type_id;
|
||||
std::map<std::string, type_ptr> types;
|
||||
std::map<std::string, constructor> constructors;
|
||||
std::map<std::string, function> functions;
|
||||
|
||||
program();
|
||||
};
|
||||
|
||||
typedef std::unique_ptr<program> program_ptr;
|
||||
|
|
32
src/type.hpp
Normal file
32
src/type.hpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace lily {
|
||||
enum reserved_types {
|
||||
type_id_int = 0,
|
||||
type_id_str,
|
||||
type_id_last
|
||||
};
|
||||
|
||||
struct type {
|
||||
virtual ~type() = default;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<type> type_ptr;
|
||||
|
||||
struct type_int : type {
|
||||
int type_id;
|
||||
|
||||
type_int(int id) : type_id(id) {}
|
||||
};
|
||||
|
||||
struct type_func : type {
|
||||
type_ptr left;
|
||||
type_ptr right;
|
||||
|
||||
type_func(type_ptr l, type_ptr r) :
|
||||
left(std::move(l)), right(std::move(r)) {}
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user