ADD: blocks.

main
bog 2023-09-19 12:50:12 +02:00
parent 820d26491a
commit f63cbf4cea
9 changed files with 122 additions and 14 deletions

20
examples/block.zn Normal file
View File

@ -0,0 +1,20 @@
($ a 2)
(assert= 2 a)
(:
($ a 9)
(assert= 9 a)
(:
($ a 42)
(assert= 42 a)
)
(assert= 9 a)
)
(assert= 2 a)
(:($ b 43))
(assert-fail b)

View File

@ -6,6 +6,7 @@ void assert_fail(Node const& node, Module& mod)
{
mod.static_pass().execute(*node.child_at(1));
mod.compiler().compile(*node.child_at(1), mod.program());
Loc loc = node.loc();
std::cerr << loc.file_path().string() << ":" << loc.line();
@ -29,6 +30,25 @@ void declare(Node const& node, Module &mod)
assert(entry);
size_t addr = mod.sym().gen_addr();
mod.sym().declare(ident, addr);
mod.sym().declare(ident, addr, entry->scope);
mod.program().append(OPCODE_STORE_LOCAL, addr);
}
void block(Node const& node, Module& mod)
{
mod.sym().enter_scope();
for (size_t i=1; i<node.size(); i++)
{
mod.static_pass().execute(*node.child_at(i));
mod.compiler().compile(*node.child_at(i), mod.program());
if (i != node.size() - 1)
{
mod.program().append(OPCODE_POP);
}
}
mod.sym().leave_scope();
}

View File

@ -7,4 +7,6 @@ void assert_fail(Node const& node, Module& mod);
void declare(Node const& node, Module& mod);
void block(Node const& node, Module& mod);
#endif

View File

@ -21,4 +21,5 @@ extern "C" void lib(Zarn& zarn)
zarn.register_macro("assert-fail", assert_fail);
zarn.register_macro("$", declare);
zarn.register_macro(":", block);
}

View File

@ -31,6 +31,10 @@ namespace zn
{
case TYPE_NIL: return "<nil>";
case TYPE_INT: return std::to_string(std::get<int>(*m_value));
case TYPE_REF: {
return "<ref " + std::to_string(std::get<int>(*m_value)) + ">";
} break;
default: {
std::cerr << "cannot stringify "
<< (TypeStr[m_type] + strlen("TYPE_"))

View File

@ -96,7 +96,7 @@ namespace zn
case NODE_IDENT: {
std::string ident = node.repr();
auto sym = m_sym.find_any(ident);
if (sym) assert(sym->scope <= m_sym.scope());
if (sym == std::nullopt)
{
std::stringstream ss;

View File

@ -12,15 +12,18 @@ namespace zn
void SymTable::prepare(std::string const& name, Type type)
{
m_syms.push_back(Sym {name, std::nullopt, type});
m_syms.push_back(Sym {name, std::nullopt, type, nullptr, m_scope});
}
void SymTable::declare(std::string const& name, size_t addr)
void SymTable::declare(std::string const& name,
size_t addr,
int scope)
{
auto itr = std::find_if(std::begin(m_syms),
std::end(m_syms),
[name](auto const& sym){
return sym.name == name;
[name, scope](auto const& sym){
return sym.name == name
&& sym.scope == scope;
});
if (itr == std::end(m_syms))
@ -35,32 +38,54 @@ namespace zn
size_t addr,
std::shared_ptr<Prototype> prototype)
{
m_syms.push_back(Sym {name, addr, TYPE_FUNCTION, prototype});
m_syms.push_back(Sym {name, addr, TYPE_FUNCTION, prototype, m_scope});
}
std::optional<Sym> SymTable::find(std::string const& name)
{
std::optional<size_t> best;
for (size_t i=0; i<m_syms.size(); i++)
{
if (name == m_syms[i].name && m_syms[i].addr != std::nullopt)
if (name == m_syms[i].name
&& m_syms[i].addr
&& (best == std::nullopt ||
(m_syms[i].scope > m_syms[*best].scope
&& m_syms[*best].scope < m_scope)))
{
return m_syms[i];
best = i;
}
}
if (best)
{
return m_syms[*best];
}
return std::nullopt;
}
std::optional<Sym> SymTable::find_any(std::string const& name)
{
std::optional<size_t> best;
for (size_t i=0; i<m_syms.size(); i++)
{
if (name == m_syms[i].name)
if (name == m_syms[i].name
&& m_syms[i].scope <= m_scope
&& (best == std::nullopt ||
(m_syms[i].scope > m_syms[*best].scope
&& m_syms[*best].scope <= m_scope)))
{
return m_syms[i];
best = i;
}
}
if (best)
{
return m_syms[*best];
}
return std::nullopt;
}
@ -70,4 +95,30 @@ namespace zn
addr++;
return addr;
}
void SymTable::enter_scope()
{
m_scope++;
}
void SymTable::leave_scope()
{
m_scope--;
}
std::string SymTable::string() const
{
std::stringstream ss;
ss << "======== " << m_scope << " ========\n";
for (auto sym: m_syms)
{
ss << sym.scope << "\t" << sym.name << " "
<< (sym.addr ? "[" + std::to_string(*sym.addr) + "]" : "[nil]")
<< "\n";
}
return ss.str();
}
}

View File

@ -3,6 +3,7 @@
#include "common.hpp"
#include "Prototype.hpp"
#include "Node.hpp"
namespace zn
{
@ -11,6 +12,7 @@ namespace zn
std::optional<size_t> addr;
Type type;
std::shared_ptr<Prototype> prototype = nullptr;
int scope = 0;
};
class SymTable
@ -19,10 +21,13 @@ namespace zn
explicit SymTable();
virtual ~SymTable();
int scope() const { return m_scope; }
size_t size() const { return m_syms.size(); }
void prepare(std::string const& name, Type type);
void declare(std::string const& name, size_t addr);
void declare(std::string const& name,
size_t addr,
int scope);
void declare_function(std::string const& name,
size_t addr,
@ -33,8 +38,13 @@ namespace zn
size_t gen_addr();
void enter_scope();
void leave_scope();
std::string string() const;
private:
std::vector<Sym> m_syms;
int m_scope = 0;
};
}