#include "StaticPass.hpp" namespace jk { /*explicit*/ StaticPass::StaticPass(std::shared_ptr sym, Logger& logger) : m_sym { sym } , m_logger { logger } { } /*virtual*/ StaticPass::~StaticPass() { } void StaticPass::pass(std::shared_ptr node) { switch (node->type()) { case NODE_PROG: case NODE_BODY: { for (size_t i=0; isize(); i++) { pass(node->child(i).lock()); pop(); } } break; case NODE_LAMBDA: { auto params = node->child(0).lock(); auto body = node->child(1).lock(); for (size_t i=0; isize(); i++) { auto param = params->child(i).lock(); std::string ident = params->child(i).lock()->repr(); m_sym->declare(ident, std::make_shared(TYPE_NIL), param->loc()); } pass(body); push(std::make_shared(TYPE_FUNCTION)); } break; case NODE_INT: { push(std::make_shared(TYPE_INT)); } break; case NODE_IDENT: { std::string ident = node->repr(); auto entry = m_sym->find(ident); if (!entry) { m_logger.log(LOG_ERROR, node->loc(), std::string() + "'" + ident + "' is undefined"); } push(entry->type); } break; case NODE_VARDECL: { std::string ident = node->child(0).lock()->repr(); pass(node->child(1).lock()); auto type = pop(); m_sym->declare(ident, type, node->loc()); push(type); } break; case NODE_FUNCALL: { for (size_t i=0; isize(); i++) { pass(node->child(i).lock()); pop(); } // TODO find actual returned type push(std::make_shared(TYPE_NIL)); } break; default: std::cerr << "cannot static_pass unknown node '" << NodeTypeStr[node->type()] << "'" << std::endl; abort(); } } void StaticPass::push(std::shared_ptr type) { m_types.push_back(type); } std::shared_ptr StaticPass::pop() { auto type = m_types.back(); m_types.pop_back(); return type; } }