diff --git a/src/compiler.cpp b/src/compiler.cpp index 6495f96..ede6204 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -7,7 +7,7 @@ struct Context { Context(Value&& env, Array&& constants, Dict&& constants_dict, Dict&& variables_dict, Array&& closures, Dict&& closures_dict, - Context* parent) + Context* parent, bool toplevel) : env(std::move(env)), constants(std::move(constants)), constants_dict(std::move(constants_dict)), @@ -27,7 +27,7 @@ struct Context { return Context(std::move(env), std::move(constants), std::move(constants_dict), std::move(variables_dict), - std::move(closures), std::move(closures_dict), 0); + std::move(closures), std::move(closures_dict), 0, true); } static Result create(Context& parent) { @@ -40,7 +40,8 @@ struct Context { return Context(std::move(env), std::move(constants), std::move(constants_dict), std::move(variables_dict), - std::move(closures), std::move(closures_dict), &parent); + std::move(closures), std::move(closures_dict), &parent, + false); } uint64_t alloc_reg() { @@ -119,6 +120,7 @@ struct Context { Dict closures_dict; uint64_t maxreg; Context* parent; + bool toplevel; }; Result Expression::add_opcode(Oc opcode, OpArg arg1, OpArg arg2, @@ -392,8 +394,8 @@ Result Compiler::compile_if(Context& context, Symbol& op, return std::move(ex); } -Result Compiler::compile_lambda(Context& context, Symbol& op, - Pair& expr) { +Result Compiler::compile_fn(Context& context, Symbol& op, + Pair& expr) { Context ctx = TRY(Context::create(context)); ctx.maxreg = 1; // Reserve the slot for function itself @@ -405,6 +407,22 @@ Result Compiler::compile_lambda(Context& context, Symbol& op, Pair& first_pair = *first.to(); + Value name = TRY(Nil::create()); + + auto maybe_name = TRY(first_pair.first()); + + if (maybe_name.is()) { + name = TRY(maybe_name.to()->copy_value()); + + first = TRY(first_pair.rest()); + + if (first.is() || !first.is()) { + return ERROR(CompilationError); + } + + Pair& first_pair = *first.to(); + } + auto param = TRY(first_pair.first()); uint64_t arity = 0; @@ -439,7 +457,6 @@ Result Compiler::compile_lambda(Context& context, Symbol& op, TRY(ex.add_opcode(Oc::Mov, {0, (int64_t)0}, {0, (int64_t)ex.reg})); TRY(ex.add_opcode(Oc::Ret, {0, (int64_t)0})); - Value name = TRY(Nil::create()); auto fun = TRY(Function::create(name, arity, ctx.constants, ex.code, TRY(Array::create()))); @@ -557,8 +574,8 @@ Result Compiler::compile_list(Context& context, Pair& expr) { return compile_comparison(context, sym, expr); } else if (TRY(sym.cmp("if")) == 0) { return compile_if(context, sym, expr); - } else if (TRY(sym.cmp("lambda")) == 0) { - return compile_lambda(context, sym, expr); + } else if (TRY(sym.cmp("fn")) == 0) { + return compile_fn(context, sym, expr); } else { return compile_function_call(context, expr); } diff --git a/src/compiler.hpp b/src/compiler.hpp index 0ef0527..25b8866 100644 --- a/src/compiler.hpp +++ b/src/compiler.hpp @@ -38,7 +38,7 @@ class Compiler { Result compile_symbol(Context& context, Symbol& value); Result compile_bool(Context& context, Bool& value); Result compile_if(Context& context, Symbol& op, Pair& expr); - Result compile_lambda(Context& context, Symbol& op, Pair& expr); + Result compile_fn(Context& context, Symbol& op, Pair& expr); Result compile_body(Context& context, Pair& expr); Result compile_function_call(Context& context, Pair& expr); }; diff --git a/src/writer.cpp b/src/writer.cpp index 2cbc0b7..bea8bf3 100644 --- a/src/writer.cpp +++ b/src/writer.cpp @@ -309,8 +309,8 @@ Result Writer::write_function(const Function& val) { return TRY(String::create("#")); } - if (!name.is()) return ERROR(TypeMismatch); - String& name_str = *name.to(); + if (!name.is()) return ERROR(TypeMismatch); + String name_str = TRY(write_symbol(*name.to())); String res = TRY(String::create("#