2019-01-19 18:28:07 +01:00
|
|
|
#include "decl.hpp"
|
|
|
|
|
#include "environ.hpp"
|
|
|
|
|
#include "ex.hpp"
|
2019-01-18 15:55:51 +01:00
|
|
|
#include "nodes.hpp"
|
2019-01-19 18:28:07 +01:00
|
|
|
#include "type.hpp"
|
|
|
|
|
#include "label.hpp"
|
|
|
|
|
#include "varnode.hpp"
|
|
|
|
|
#include "codegen.hpp"
|
|
|
|
|
|
|
|
|
|
#include <stdutil.hpp>
|
|
|
|
|
#include "declnode.hpp"
|
|
|
|
|
|
|
|
|
|
DeclSeqNode::DeclSeqNode() {}
|
|
|
|
|
|
|
|
|
|
DeclSeqNode::~DeclSeqNode()
|
|
|
|
|
{
|
|
|
|
|
for (; decls.size(); decls.pop_back())
|
|
|
|
|
delete decls.back();
|
|
|
|
|
}
|
2014-01-31 08:23:00 +13:00
|
|
|
|
|
|
|
|
//////////////////////////////
|
|
|
|
|
// Sequence of declarations //
|
|
|
|
|
//////////////////////////////
|
2019-01-18 17:04:57 +01:00
|
|
|
void DeclSeqNode::proto(DeclSeq* d, Environ* e)
|
|
|
|
|
{
|
2017-04-09 05:35:18 +02:00
|
|
|
for (size_t k = 0; k < decls.size(); ++k) {
|
2019-01-18 17:04:57 +01:00
|
|
|
try {
|
|
|
|
|
decls[k]->proto(d, e);
|
2019-01-19 18:28:07 +01:00
|
|
|
} catch (BlitzException& x) {
|
2019-01-18 17:04:57 +01:00
|
|
|
if (x.pos < 0)
|
|
|
|
|
x.pos = decls[k]->pos;
|
|
|
|
|
if (!x.file.size())
|
|
|
|
|
x.file = decls[k]->file;
|
2016-05-07 22:49:54 +02:00
|
|
|
throw;
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void DeclSeqNode::semant(Environ* e)
|
|
|
|
|
{
|
2017-04-09 05:35:18 +02:00
|
|
|
for (size_t k = 0; k < decls.size(); ++k) {
|
2019-01-18 17:04:57 +01:00
|
|
|
try {
|
|
|
|
|
decls[k]->semant(e);
|
2019-01-19 18:28:07 +01:00
|
|
|
} catch (BlitzException& x) {
|
2019-01-18 17:04:57 +01:00
|
|
|
if (x.pos < 0)
|
|
|
|
|
x.pos = decls[k]->pos;
|
|
|
|
|
if (!x.file.size())
|
|
|
|
|
x.file = decls[k]->file;
|
2016-05-07 22:49:54 +02:00
|
|
|
throw;
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void DeclSeqNode::translate(Codegen* g)
|
|
|
|
|
{
|
2017-04-09 05:35:18 +02:00
|
|
|
for (size_t k = 0; k < decls.size(); ++k) {
|
2019-01-18 17:04:57 +01:00
|
|
|
try {
|
|
|
|
|
decls[k]->translate(g);
|
2019-01-19 18:28:07 +01:00
|
|
|
} catch (BlitzException& x) {
|
2019-01-18 17:04:57 +01:00
|
|
|
if (x.pos < 0)
|
|
|
|
|
x.pos = decls[k]->pos;
|
|
|
|
|
if (!x.file.size())
|
|
|
|
|
x.file = decls[k]->file;
|
2016-05-07 22:49:54 +02:00
|
|
|
throw;
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void DeclSeqNode::transdata(Codegen* g)
|
|
|
|
|
{
|
2017-04-09 05:35:18 +02:00
|
|
|
for (size_t k = 0; k < decls.size(); ++k) {
|
2019-01-18 17:04:57 +01:00
|
|
|
try {
|
|
|
|
|
decls[k]->transdata(g);
|
2019-01-19 18:28:07 +01:00
|
|
|
} catch (BlitzException& x) {
|
2019-01-18 17:04:57 +01:00
|
|
|
if (x.pos < 0)
|
|
|
|
|
x.pos = decls[k]->pos;
|
|
|
|
|
if (!x.file.size())
|
|
|
|
|
x.file = decls[k]->file;
|
2016-05-07 22:49:54 +02:00
|
|
|
throw;
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-19 18:28:07 +01:00
|
|
|
void DeclSeqNode::push_back(DeclNode* d)
|
|
|
|
|
{
|
|
|
|
|
decls.push_back(d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int DeclSeqNode::size()
|
|
|
|
|
{
|
|
|
|
|
return decls.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VarDeclNode::VarDeclNode(const std::string& i, const std::string& t, int k, bool c, ExprNode* e)
|
|
|
|
|
: ident(i), tag(t), kind(k), constant(c), expr(e), sem_var(0)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
VarDeclNode::~VarDeclNode()
|
|
|
|
|
{
|
|
|
|
|
delete expr;
|
|
|
|
|
delete sem_var;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-31 08:23:00 +13:00
|
|
|
////////////////////////////
|
|
|
|
|
// Simple var declaration //
|
|
|
|
|
////////////////////////////
|
2019-01-18 17:04:57 +01:00
|
|
|
void VarDeclNode::proto(DeclSeq* d, Environ* e)
|
|
|
|
|
{
|
|
|
|
|
Type* ty = tagType(tag, e);
|
|
|
|
|
if (!ty)
|
|
|
|
|
ty = Type::int_type;
|
|
|
|
|
ConstType* defType = 0;
|
2016-05-07 22:49:54 +02:00
|
|
|
|
|
|
|
|
if (expr != nullptr) {
|
|
|
|
|
expr->semant(e);
|
|
|
|
|
if (expr == nullptr) {
|
|
|
|
|
ex("Internal Error: expr turned into nullptr (1)");
|
|
|
|
|
}
|
|
|
|
|
expr = expr->castTo(ty, e);
|
|
|
|
|
if (expr == nullptr) {
|
|
|
|
|
ex("Internal Error: expr turned into nullptr (2)");
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-07 23:09:58 +02:00
|
|
|
if (constant || (kind & DECL_PARAM)) {
|
2019-01-18 17:04:57 +01:00
|
|
|
ConstNode* c = static_cast<ConstNode*>(expr); //->constNode();
|
|
|
|
|
|
|
|
|
|
if (!c)
|
|
|
|
|
ex("Expression must be constant");
|
|
|
|
|
if (ty == Type::int_type)
|
|
|
|
|
ty = new ConstType(c->intValue());
|
|
|
|
|
else if (ty == Type::float_type)
|
|
|
|
|
ty = new ConstType(c->floatValue());
|
|
|
|
|
else
|
|
|
|
|
ty = new ConstType(c->stringValue());
|
2016-05-07 22:49:54 +02:00
|
|
|
e->types.push_back(ty);
|
2019-01-18 17:04:57 +01:00
|
|
|
delete expr;
|
|
|
|
|
expr = 0;
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
2016-05-07 23:09:58 +02:00
|
|
|
|
2016-05-07 23:13:21 +02:00
|
|
|
if (expr == nullptr) {
|
|
|
|
|
ex("Internal Error: expr turned into nullptr (3)");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (kind & DECL_PARAM) { // Heap corruption, this being replaced again?
|
2019-01-18 17:04:57 +01:00
|
|
|
defType = ty->constType();
|
|
|
|
|
ty = defType->valueType;
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
2019-01-18 17:04:57 +01:00
|
|
|
} else if (constant)
|
|
|
|
|
ex("Constants must be initialized");
|
|
|
|
|
|
|
|
|
|
Decl* decl = d->insertDecl(ident, ty, kind, defType);
|
|
|
|
|
if (!decl)
|
|
|
|
|
ex("Duplicate variable name");
|
|
|
|
|
if (expr)
|
|
|
|
|
sem_var = new DeclVarNode(decl);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void VarDeclNode::semant(Environ* e) {}
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void VarDeclNode::translate(Codegen* g)
|
|
|
|
|
{
|
2016-05-07 22:49:54 +02:00
|
|
|
if (kind & DECL_GLOBAL) {
|
|
|
|
|
g->align_data(4);
|
|
|
|
|
g->i_data(0, "_v" + ident);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
2019-01-18 17:04:57 +01:00
|
|
|
if (expr)
|
|
|
|
|
g->code(sem_var->store(g, expr->translate(g)));
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-19 18:28:07 +01:00
|
|
|
FuncDeclNode::FuncDeclNode(const std::string& i, const std::string& t, DeclSeqNode* p, StmtSeqNode* ss)
|
|
|
|
|
: ident(i), tag(t), params(p), stmts(ss)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
FuncDeclNode::~FuncDeclNode()
|
|
|
|
|
{
|
|
|
|
|
delete params;
|
|
|
|
|
delete stmts;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-31 08:23:00 +13:00
|
|
|
//////////////////////////
|
|
|
|
|
// Function Declaration //
|
|
|
|
|
//////////////////////////
|
2019-01-18 17:04:57 +01:00
|
|
|
void FuncDeclNode::proto(DeclSeq* d, Environ* e)
|
|
|
|
|
{
|
|
|
|
|
Type* t = tagType(tag, e);
|
|
|
|
|
if (!t)
|
|
|
|
|
t = Type::int_type;
|
2016-10-03 17:11:15 +02:00
|
|
|
a_ptr<DeclSeq> decls(new DeclSeq());
|
2016-05-07 22:49:54 +02:00
|
|
|
params->proto(decls, e);
|
2016-10-03 17:11:15 +02:00
|
|
|
sem_type = new FuncType(t, decls.release(), false, false);
|
2016-05-07 22:49:54 +02:00
|
|
|
if (!d->insertDecl(ident, sem_type, DECL_FUNC)) {
|
2019-01-18 17:04:57 +01:00
|
|
|
delete sem_type;
|
|
|
|
|
ex("duplicate identifier");
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
2016-05-07 22:49:54 +02:00
|
|
|
e->types.push_back(sem_type);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void FuncDeclNode::semant(Environ* e)
|
|
|
|
|
{
|
|
|
|
|
sem_env = new Environ(genLabel(), sem_type->returnType, 1, e);
|
|
|
|
|
DeclSeq* decls = sem_env->decls;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
|
|
|
|
int k;
|
2016-05-07 22:49:54 +02:00
|
|
|
for (k = 0; k < sem_type->params->size(); ++k) {
|
2019-01-18 17:04:57 +01:00
|
|
|
Decl* d = sem_type->params->decls[k];
|
|
|
|
|
if (!decls->insertDecl(d->name, d->type, d->kind))
|
|
|
|
|
ex("duplicate identifier");
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2016-05-07 22:49:54 +02:00
|
|
|
stmts->semant(sem_env);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void FuncDeclNode::translate(Codegen* g)
|
|
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
//var offsets
|
2016-05-07 22:49:54 +02:00
|
|
|
int size = enumVars(sem_env);
|
2014-01-31 08:23:00 +13:00
|
|
|
|
|
|
|
|
//enter function
|
2016-05-07 22:49:54 +02:00
|
|
|
g->enter("_f" + ident, size);
|
2014-01-31 08:23:00 +13:00
|
|
|
|
|
|
|
|
//initialize locals
|
2019-01-18 17:04:57 +01:00
|
|
|
TNode* t = createVars(sem_env);
|
|
|
|
|
if (t)
|
|
|
|
|
g->code(t);
|
2016-05-07 22:49:54 +02:00
|
|
|
if (g->debug) {
|
2019-01-19 18:28:07 +01:00
|
|
|
std::string t = genLabel();
|
2016-05-07 22:49:54 +02:00
|
|
|
g->s_data(ident, t);
|
|
|
|
|
g->code(call("__bbDebugEnter", local(0), iconst((int)sem_env), global(t)));
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//translate statements
|
2016-05-07 22:49:54 +02:00
|
|
|
stmts->translate(g);
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2017-04-09 05:35:18 +02:00
|
|
|
for (size_t k = 0; k < sem_env->labels.size(); ++k) {
|
2019-01-18 17:04:57 +01:00
|
|
|
if (sem_env->labels[k]->def < 0)
|
|
|
|
|
ex("Undefined label", sem_env->labels[k]->ref);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//leave the function
|
2016-05-07 22:49:54 +02:00
|
|
|
g->label(sem_env->funcLabel + "_leave");
|
|
|
|
|
t = deleteVars(sem_env);
|
2019-01-18 17:04:57 +01:00
|
|
|
if (g->debug)
|
|
|
|
|
t = new TNode(IR_SEQ, call("__bbDebugLeave"), t);
|
2016-05-07 22:49:54 +02:00
|
|
|
g->leave(t, sem_type->params->size() * 4);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-19 18:28:07 +01:00
|
|
|
StructDeclNode::StructDeclNode(const std::string& i, DeclSeqNode* f) : ident(i), fields(f) {}
|
|
|
|
|
|
|
|
|
|
StructDeclNode::~StructDeclNode()
|
|
|
|
|
{
|
|
|
|
|
delete fields;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-31 08:23:00 +13:00
|
|
|
//////////////////////
|
|
|
|
|
// Type Declaration //
|
|
|
|
|
//////////////////////
|
2019-01-18 17:04:57 +01:00
|
|
|
void StructDeclNode::proto(DeclSeq* d, Environ* e)
|
|
|
|
|
{
|
2016-10-03 17:11:15 +02:00
|
|
|
sem_type = new StructType(ident, new DeclSeq());
|
2016-05-07 22:49:54 +02:00
|
|
|
if (!d->insertDecl(ident, sem_type, DECL_STRUCT)) {
|
2019-01-18 17:04:57 +01:00
|
|
|
delete sem_type;
|
|
|
|
|
ex("Duplicate identifier");
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
2016-05-07 22:49:54 +02:00
|
|
|
e->types.push_back(sem_type);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void StructDeclNode::semant(Environ* e)
|
|
|
|
|
{
|
2016-05-07 22:49:54 +02:00
|
|
|
fields->proto(sem_type->fields, e);
|
2019-01-18 17:04:57 +01:00
|
|
|
for (int k = 0; k < sem_type->fields->size(); ++k)
|
|
|
|
|
sem_type->fields->decls[k]->offset = k * 4;
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void StructDeclNode::translate(Codegen* g)
|
|
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
//translate fields
|
2016-05-07 22:49:54 +02:00
|
|
|
fields->translate(g);
|
2014-01-31 08:23:00 +13:00
|
|
|
|
|
|
|
|
//type ID
|
2016-05-07 22:49:54 +02:00
|
|
|
g->align_data(4);
|
|
|
|
|
g->i_data(5, "_t" + ident);
|
2014-01-31 08:23:00 +13:00
|
|
|
|
|
|
|
|
//used and free lists for type
|
|
|
|
|
int k;
|
2016-05-07 22:49:54 +02:00
|
|
|
for (k = 0; k < 2; ++k) {
|
2019-01-19 18:28:07 +01:00
|
|
|
std::string lab = genLabel();
|
2019-01-18 17:04:57 +01:00
|
|
|
g->i_data(0, lab); //fields
|
|
|
|
|
g->p_data(lab); //next
|
|
|
|
|
g->p_data(lab); //prev
|
|
|
|
|
g->i_data(0); //type
|
|
|
|
|
g->i_data(-1); //ref_cnt
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//number of fields
|
2016-05-07 22:49:54 +02:00
|
|
|
g->i_data(sem_type->fields->size());
|
2014-01-31 08:23:00 +13:00
|
|
|
|
|
|
|
|
//type of each field
|
2016-05-07 22:49:54 +02:00
|
|
|
for (k = 0; k < sem_type->fields->size(); ++k) {
|
2019-01-19 18:28:07 +01:00
|
|
|
Decl* field = sem_type->fields->decls[k];
|
|
|
|
|
Type* type = field->type;
|
|
|
|
|
std::string t;
|
2019-01-18 17:04:57 +01:00
|
|
|
if (type == Type::int_type)
|
|
|
|
|
t = "__bbIntType";
|
|
|
|
|
else if (type == Type::float_type)
|
|
|
|
|
t = "__bbFltType";
|
|
|
|
|
else if (type == Type::string_type)
|
|
|
|
|
t = "__bbStrType";
|
|
|
|
|
else if (StructType* s = type->structType())
|
|
|
|
|
t = "_t" + s->ident;
|
|
|
|
|
else if (VectorType* v = type->vectorType())
|
|
|
|
|
t = v->label;
|
2016-05-07 22:49:54 +02:00
|
|
|
g->p_data(t);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-19 18:28:07 +01:00
|
|
|
DataDeclNode::DataDeclNode(ExprNode* e) : expr(e) {}
|
|
|
|
|
|
|
|
|
|
DataDeclNode::~DataDeclNode()
|
|
|
|
|
{
|
|
|
|
|
delete expr;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-31 08:23:00 +13:00
|
|
|
//////////////////////
|
|
|
|
|
// Data declaration //
|
|
|
|
|
//////////////////////
|
2019-01-18 17:04:57 +01:00
|
|
|
void DataDeclNode::proto(DeclSeq* d, Environ* e)
|
|
|
|
|
{
|
|
|
|
|
expr = expr->semant(e);
|
|
|
|
|
ConstNode* c = expr->constNode();
|
|
|
|
|
if (!c)
|
|
|
|
|
ex("Data expression must be constant");
|
|
|
|
|
if (expr->sem_type == Type::string_type)
|
|
|
|
|
str_label = genLabel();
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void DataDeclNode::semant(Environ* e) {}
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void DataDeclNode::translate(Codegen* g)
|
|
|
|
|
{
|
|
|
|
|
if (expr->sem_type != Type::string_type)
|
|
|
|
|
return;
|
|
|
|
|
ConstNode* c = expr->constNode();
|
2016-05-07 22:49:54 +02:00
|
|
|
g->s_data(c->stringValue(), str_label);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void DataDeclNode::transdata(Codegen* g)
|
|
|
|
|
{
|
|
|
|
|
ConstNode* c = expr->constNode();
|
2016-05-07 22:49:54 +02:00
|
|
|
if (expr->sem_type == Type::int_type) {
|
2019-01-18 17:04:57 +01:00
|
|
|
g->i_data(1);
|
|
|
|
|
g->i_data(c->intValue());
|
2016-05-07 22:49:54 +02:00
|
|
|
} else if (expr->sem_type == Type::float_type) {
|
|
|
|
|
float n = c->floatValue();
|
2019-01-18 17:04:57 +01:00
|
|
|
g->i_data(2);
|
|
|
|
|
g->i_data(*(int*)&n);
|
2016-05-07 22:49:54 +02:00
|
|
|
} else {
|
2019-01-18 17:04:57 +01:00
|
|
|
g->i_data(4);
|
|
|
|
|
g->p_data(str_label);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-19 18:28:07 +01:00
|
|
|
VectorDeclNode::VectorDeclNode(const std::string& i, const std::string& t, ExprSeqNode* e, int k)
|
|
|
|
|
: ident(i), tag(t), exprs(e), kind(k)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
VectorDeclNode::~VectorDeclNode()
|
|
|
|
|
{
|
|
|
|
|
delete exprs;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-31 08:23:00 +13:00
|
|
|
////////////////////////
|
|
|
|
|
// Vector declaration //
|
|
|
|
|
////////////////////////
|
2019-01-18 17:04:57 +01:00
|
|
|
void VectorDeclNode::proto(DeclSeq* d, Environ* env)
|
|
|
|
|
{
|
|
|
|
|
Type* ty = tagType(tag, env);
|
|
|
|
|
if (!ty)
|
|
|
|
|
ty = Type::int_type;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-19 18:28:07 +01:00
|
|
|
std::vector<int> sizes;
|
2016-05-07 22:49:54 +02:00
|
|
|
for (int k = 0; k < exprs->size(); ++k) {
|
2019-01-18 17:04:57 +01:00
|
|
|
ExprNode* e = exprs->exprs[k] = exprs->exprs[k]->semant(env);
|
|
|
|
|
ConstNode* c = e->constNode();
|
|
|
|
|
if (!c)
|
|
|
|
|
ex("Blitz array sizes must be constant");
|
2016-05-07 22:49:54 +02:00
|
|
|
int n = c->intValue();
|
2019-01-18 17:04:57 +01:00
|
|
|
if (n < 0)
|
|
|
|
|
ex("Blitz array sizes must not be negative");
|
2016-05-07 22:49:54 +02:00
|
|
|
sizes.push_back(n + 1);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
2019-01-19 18:28:07 +01:00
|
|
|
std::string label = genLabel();
|
|
|
|
|
sem_type = new VectorType(label, ty, sizes);
|
2016-05-07 22:49:54 +02:00
|
|
|
if (!d->insertDecl(ident, sem_type, kind)) {
|
2019-01-18 17:04:57 +01:00
|
|
|
delete sem_type;
|
|
|
|
|
ex("Duplicate identifier");
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
2016-05-07 22:49:54 +02:00
|
|
|
env->types.push_back(sem_type);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
void VectorDeclNode::translate(Codegen* g)
|
|
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
//type tag!
|
2016-05-07 22:49:54 +02:00
|
|
|
g->align_data(4);
|
2019-01-18 17:04:57 +01:00
|
|
|
VectorType* v = sem_type->vectorType();
|
2016-05-07 22:49:54 +02:00
|
|
|
g->i_data(6, v->label);
|
|
|
|
|
int sz = 1;
|
2019-01-18 17:04:57 +01:00
|
|
|
for (size_t k = 0; k < v->sizes.size(); ++k)
|
|
|
|
|
sz *= v->sizes[k];
|
2016-05-07 22:49:54 +02:00
|
|
|
g->i_data(sz);
|
2019-01-19 18:28:07 +01:00
|
|
|
std::string t;
|
|
|
|
|
Type* type = v->elementType;
|
2019-01-18 17:04:57 +01:00
|
|
|
if (type == Type::int_type)
|
|
|
|
|
t = "__bbIntType";
|
|
|
|
|
else if (type == Type::float_type)
|
|
|
|
|
t = "__bbFltType";
|
|
|
|
|
else if (type == Type::string_type)
|
|
|
|
|
t = "__bbStrType";
|
|
|
|
|
else if (StructType* s = type->structType())
|
|
|
|
|
t = "_t" + s->ident;
|
|
|
|
|
else if (VectorType* v = type->vectorType())
|
|
|
|
|
t = v->label;
|
2016-05-07 22:49:54 +02:00
|
|
|
g->p_data(t);
|
|
|
|
|
|
2019-01-18 17:04:57 +01:00
|
|
|
if (kind == DECL_GLOBAL)
|
|
|
|
|
g->i_data(0, "_v" + ident);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
2019-01-19 18:28:07 +01:00
|
|
|
|
|
|
|
|
DeclNode::DeclNode() : pos(-1) {}
|
|
|
|
|
|
|
|
|
|
void DeclNode::proto(DeclSeq* d, Environ* e) {}
|
|
|
|
|
|
|
|
|
|
void DeclNode::semant(Environ* e) {}
|
|
|
|
|
|
|
|
|
|
void DeclNode::translate(Codegen* g) {}
|
|
|
|
|
|
|
|
|
|
void DeclNode::transdata(Codegen* g) {}
|