<commit_before>/**
 * Clever programming language
 * Copyright (c) Clever Team
 *
 * This file is distributed under the MIT license. See LICENSE for details.
 */

#include <iostream>
#include "core/ast.h"
#include "core/codegen.h"
#include "core/scope.h"
#include "core/compiler.h"

namespace clever { namespace ast {

void Codegen::init()
{
	m_scope = new Scope;
	m_scope_pool[m_scope_id++] = m_scope;
}

void Codegen::visit(IntLit* node)
{
	node->setConstId(m_compiler->addConstant(new Value(node->getValue())));
}

void Codegen::visit(DoubleLit* node)
{
	node->setConstId(m_compiler->addConstant(new Value(node->getValue())));
}

void Codegen::visit(StringLit* node)
{
	node->setConstId(m_compiler->addConstant(new Value(node->getValue())));
}

void Codegen::visit(Ident* node)
{
	Symbol* sym = m_scope->getAny(node->getName());

	if (!sym) {
		m_compiler->errorf(node->getLocation(),
			"Variable `%S' not found!", node->getName());
	}
	std::cout << "id: " << sym->value_id << std::endl;

	node->setValueId(sym->value_id);
	node->setScopeId(sym->scope->getId());
}

void Codegen::visit(Import* node)
{
	if (node->getModule()) {
		m_compiler->getPkgManager().importModule(m_scope,
			node->getPackage()->getName(), node->getModule()->getName());
	} else {
		m_compiler->getPkgManager().importPackage(m_scope,
			node->getPackage()->getName());
	}
}

void Codegen::visit(Block* node)
{
	m_scope = m_scope->newLexicalScope();
	m_scope->setId(m_scope_id);
	m_scope_pool[m_scope_id++] = m_scope;

	std::vector<Node*> nodes = node->getNodes();
	std::vector<Node*>::const_iterator it = nodes.begin(), end = nodes.end();
	while (it != end) {
		(*it)->accept(*this);
		++it;
	}

	m_scope = m_scope->getParent();
}

void Codegen::visit(VariableDecl* node)
{
	if (node->hasAssignment()) {
		m_scope->pushValue(node->getIdent()->getName(), new Value());
		node->getAssignment()->accept(*this);
	} else {
		size_t var_id = m_scope->pushValue(node->getIdent()->getName(), new Value());

		m_ir.push_back(
			IR(OP_ASSIGN,
				Operand(FETCH_VAL, var_id, m_scope->getId()),
				Operand(FETCH_VAL, m_scope->pushConst(new Value()), m_scope->getId())));
	}
}

void Codegen::visit(Assignment* node)
{
	// TODO: allow assignment of any possible left hand side.

	Ident* ident = static_cast<Ident*>(node->getLhs());
	Symbol* sym = m_scope->getLocal(ident->getName());
	Node* rhs = node->getRhs();

	if (!sym) {
		m_compiler->errorf(node->getLocation(),
			"Variable `%S' not found!", ident->getName());
	}

	rhs->accept(*this);

	if (rhs->isLiteral()) {
		m_ir.push_back(IR(OP_ASSIGN,
			Operand(FETCH_VAL, sym->value_id, sym->scope->getId()),
			Operand(FETCH_CONST, static_cast<Literal*>(rhs)->getConstId())));
	}

	// TODO: if node->isConditional() is true, emit branching code to avoid assignment when ident has been initialized.
}

void Codegen::visit(FunctionCall* node)
{
	Ident* ident = static_cast<Ident*>(node->getCallee());
	Symbol* sym = m_scope->getAny(ident->getName());

	if (!sym) {
		m_compiler->errorf(node->getLocation(),
			"Function `%S' not found!", ident->getName());
	}

	if (node->hasArgs()) {
		NodeList& args = node->getArgs()->getNodes();
		NodeList::const_iterator it = args.begin(), end = args.end();

		while (it != end) {
			Operand operand;

			(*it)->accept(*this);

			if ((*it)->isLiteral()) {
				operand.op_type = FETCH_CONST;
				operand.value_id = static_cast<Literal*>(*it)->getConstId();
			} else {
				std::cout << "foo" << std::endl;

				operand.op_type = FETCH_VAL;
				operand.value_id = (*it)->getValueId();
				operand.scope_id = (*it)->getScopeId();
			}
			m_ir.push_back(IR(OP_SEND_VAL, operand));
			++it;
		}
	}

	m_ir.push_back(IR(OP_FCALL,
		Operand(FETCH_VAL, sym->value_id, sym->scope->getId())));
}

void Codegen::visit(FunctionDecl* node)
{
	const CString* name = node->getIdent()->getName();
	Symbol* sym = m_scope->getLocal(name);
	size_t start_func;

	if (sym) {
		m_compiler->errorf(node->getLocation(),
			"Function `%S' already defined in the scope!", name);
	}

	Function* func = static_cast<Function*>(CLEVER_FUNC_TYPE->allocData());

	func->setName(*name);
	func->setUserDefined();<commit_msg>- Removed debug prints<commit_after>/**
 * Clever programming language
 * Copyright (c) Clever Team
 *
 * This file is distributed under the MIT license. See LICENSE for details.
 */

#include <iostream>
#include "core/ast.h"
#include "core/codegen.h"
#include "core/scope.h"
#include "core/compiler.h"

namespace clever { namespace ast {

void Codegen::init()
{
	m_scope = new Scope;
	m_scope_pool[m_scope_id++] = m_scope;
}

void Codegen::visit(IntLit* node)
{
	node->setConstId(m_compiler->addConstant(new Value(node->getValue())));
}

void Codegen::visit(DoubleLit* node)
{
	node->setConstId(m_compiler->addConstant(new Value(node->getValue())));
}

void Codegen::visit(StringLit* node)
{
	node->setConstId(m_compiler->addConstant(new Value(node->getValue())));
}

void Codegen::visit(Ident* node)
{
	Symbol* sym = m_scope->getAny(node->getName());

	if (!sym) {
		m_compiler->errorf(node->getLocation(),
			"Variable `%S' not found!", node->getName());
	}

	node->setValueId(sym->value_id);
	node->setScopeId(sym->scope->getId());
}

void Codegen::visit(Import* node)
{
	if (node->getModule()) {
		m_compiler->getPkgManager().importModule(m_scope,
			node->getPackage()->getName(), node->getModule()->getName());
	} else {
		m_compiler->getPkgManager().importPackage(m_scope,
			node->getPackage()->getName());
	}
}

void Codegen::visit(Block* node)
{
	m_scope = m_scope->newLexicalScope();
	m_scope->setId(m_scope_id);
	m_scope_pool[m_scope_id++] = m_scope;

	std::vector<Node*> nodes = node->getNodes();
	std::vector<Node*>::const_iterator it = nodes.begin(), end = nodes.end();
	while (it != end) {
		(*it)->accept(*this);
		++it;
	}

	m_scope = m_scope->getParent();
}

void Codegen::visit(VariableDecl* node)
{
	if (node->hasAssignment()) {
		m_scope->pushValue(node->getIdent()->getName(), new Value());
		node->getAssignment()->accept(*this);
	} else {
		size_t var_id = m_scope->pushValue(node->getIdent()->getName(), new Value());

		m_ir.push_back(
			IR(OP_ASSIGN,
				Operand(FETCH_VAL, var_id, m_scope->getId()),
				Operand(FETCH_VAL, m_scope->pushConst(new Value()), m_scope->getId())));
	}
}

void Codegen::visit(Assignment* node)
{
	// TODO: allow assignment of any possible left hand side.

	Ident* ident = static_cast<Ident*>(node->getLhs());
	Symbol* sym = m_scope->getLocal(ident->getName());
	Node* rhs = node->getRhs();

	if (!sym) {
		m_compiler->errorf(node->getLocation(),
			"Variable `%S' not found!", ident->getName());
	}

	rhs->accept(*this);

	if (rhs->isLiteral()) {
		m_ir.push_back(IR(OP_ASSIGN,
			Operand(FETCH_VAL, sym->value_id, sym->scope->getId()),
			Operand(FETCH_CONST, static_cast<Literal*>(rhs)->getConstId())));
	}

	// TODO: if node->isConditional() is true, emit branching code to avoid assignment when ident has been initialized.
}

void Codegen::visit(FunctionCall* node)
{
	Ident* ident = static_cast<Ident*>(node->getCallee());
	Symbol* sym = m_scope->getAny(ident->getName());

	if (!sym) {
		m_compiler->errorf(node->getLocation(),
			"Function `%S' not found!", ident->getName());
	}

	if (node->hasArgs()) {
		NodeList& args = node->getArgs()->getNodes();
		NodeList::const_iterator it = args.begin(), end = args.end();

		while (it != end) {
			Operand operand;

			(*it)->accept(*this);

			if ((*it)->isLiteral()) {
				operand.op_type = FETCH_CONST;
				operand.value_id = static_cast<Literal*>(*it)->getConstId();
			} else {
				operand.op_type = FETCH_VAL;
				operand.value_id = (*it)->getValueId();
				operand.scope_id = (*it)->getScopeId();
			}
			m_ir.push_back(IR(OP_SEND_VAL, operand));
			++it;
		}
	}

	m_ir.push_back(IR(OP_FCALL,
		Operand(FETCH_VAL, sym->value_id, sym->scope->getId())));
}

void Codegen::visit(FunctionDecl* node)
{
	const CString* name = node->getIdent()->getName();
	Symbol* sym = m_scope->getLocal(name);
	size_t start_func;

	if (sym) {
		m_compiler->errorf(node->getLocation(),
			"Function `%S' already defined in the scope!", name);
	}

	Function* func = static_cast<Function*>(CLEVER_FUNC_TYPE->allocData());

	func->setName(*name);
	func->setUserDefined();
{'fraction_non_alphanumeric': 0.19442075770495798, 'fraction_numerical': 0.0, 'mean_word_length': 5.059040590405904, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 188, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6047073', 'n_tokens_mistral': 3138, 'n_tokens_neox': 2974, 'n_words': 539}