compiler: Move and modernize
compiler is blitzcc, what I previously called compiler is now compiler_lib
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
#include "varnode.hpp"
|
||||
#include "codegen.hpp"
|
||||
#include "environ.hpp"
|
||||
#include "exprnode.hpp"
|
||||
#include "type.hpp"
|
||||
|
||||
//////////////////////////////////
|
||||
// Common get/set for variables //
|
||||
//////////////////////////////////
|
||||
TNode* VarNode::load(Codegen* g)
|
||||
{
|
||||
TNode* t = translate(g);
|
||||
if (sem_type == Type::string_type)
|
||||
return call("__bbStrLoad", t);
|
||||
return mem(t);
|
||||
}
|
||||
|
||||
TNode* VarNode::store(Codegen* g, TNode* n)
|
||||
{
|
||||
TNode* t = translate(g);
|
||||
if (sem_type->structType())
|
||||
return call("__bbObjStore", t, n);
|
||||
if (sem_type == Type::string_type)
|
||||
return call("__bbStrStore", t, n);
|
||||
return move(n, mem(t));
|
||||
}
|
||||
|
||||
bool VarNode::isObjParam()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DeclVarNode::DeclVarNode(Decl* d) : sem_decl(d)
|
||||
{
|
||||
if (d)
|
||||
sem_type = d->type;
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// Declared var //
|
||||
//////////////////
|
||||
void DeclVarNode::semant(Environ* e) {}
|
||||
|
||||
TNode* DeclVarNode::translate(Codegen* g)
|
||||
{
|
||||
if (sem_decl->kind == DECL_GLOBAL)
|
||||
return global("_v" + sem_decl->name);
|
||||
return local(sem_decl->offset);
|
||||
}
|
||||
|
||||
TNode* DeclVarNode::store(Codegen* g, TNode* n)
|
||||
{
|
||||
if (isObjParam()) {
|
||||
TNode* t = translate(g);
|
||||
return move(n, mem(t));
|
||||
}
|
||||
return VarNode::store(g, n);
|
||||
}
|
||||
|
||||
bool DeclVarNode::isObjParam()
|
||||
{
|
||||
return sem_type->structType() && sem_decl->kind == DECL_PARAM;
|
||||
}
|
||||
|
||||
IdentVarNode::IdentVarNode(const std::string& i, const std::string& t) : ident(i), tag(t) {}
|
||||
|
||||
///////////////
|
||||
// Ident var //
|
||||
///////////////
|
||||
void IdentVarNode::semant(Environ* e)
|
||||
{
|
||||
if (sem_decl)
|
||||
return;
|
||||
Type* t = tagType(tag, e);
|
||||
if (!t)
|
||||
t = Type::int_type;
|
||||
if (sem_decl = e->findDecl(ident)) {
|
||||
if (!(sem_decl->kind & (DECL_GLOBAL | DECL_LOCAL | DECL_PARAM))) {
|
||||
ex("Identifier '" + sem_decl->name + "' may not be used like this");
|
||||
}
|
||||
Type* ty = sem_decl->type;
|
||||
if (ty->constType())
|
||||
ty = ty->constType()->valueType;
|
||||
if (tag.size() && t != ty)
|
||||
ex("Variable type mismatch");
|
||||
} else {
|
||||
//ugly auto decl!
|
||||
sem_decl = e->decls->insertDecl(ident, t, DECL_LOCAL);
|
||||
}
|
||||
sem_type = sem_decl->type;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Indexed Var //
|
||||
/////////////////
|
||||
void ArrayVarNode::semant(Environ* e)
|
||||
{
|
||||
exprs->semant(e);
|
||||
exprs->castTo(Type::int_type, e);
|
||||
Type* t = e->findType(tag);
|
||||
sem_decl = e->findDecl(ident);
|
||||
if (!sem_decl || !(sem_decl->kind & DECL_ARRAY))
|
||||
ex("Array not found");
|
||||
ArrayType* a = sem_decl->type->arrayType();
|
||||
if (t && t != a->type)
|
||||
ex("array type mismtach");
|
||||
if (a->size != exprs->size())
|
||||
ex("incorrect number of dimensions");
|
||||
sem_type = a->type;
|
||||
}
|
||||
|
||||
TNode* ArrayVarNode::translate(Codegen* g)
|
||||
{
|
||||
TNode* t = 0;
|
||||
for (int k = 0; k < exprs->size(); ++k) {
|
||||
TNode* e = exprs->exprs[k]->translate(g);
|
||||
if (k) {
|
||||
TNode* s = mem(add(global("_a" + ident), iconst(k * 4 + 8)));
|
||||
e = add(t, mul(e, s));
|
||||
}
|
||||
if (g->debug) {
|
||||
TNode* s = mem(add(global("_a" + ident), iconst(k * 4 + 12)));
|
||||
t = jumpge(e, s, "__bbArrayBoundsEx");
|
||||
} else
|
||||
t = e;
|
||||
}
|
||||
t = add(mem(global("_a" + ident)), mul(t, iconst(4)));
|
||||
return t;
|
||||
}
|
||||
|
||||
///////////////
|
||||
// Field var //
|
||||
///////////////
|
||||
void FieldVarNode::semant(Environ* e)
|
||||
{
|
||||
expr = expr->semant(e);
|
||||
StructType* s = expr->sem_type->structType();
|
||||
if (!s)
|
||||
ex("Variable must be a Type");
|
||||
sem_field = s->fields->findDecl(ident);
|
||||
if (!sem_field)
|
||||
ex("Type field not found");
|
||||
sem_type = sem_field->type;
|
||||
}
|
||||
|
||||
TNode* FieldVarNode::translate(Codegen* g)
|
||||
{
|
||||
TNode* t = expr->translate(g);
|
||||
if (g->debug)
|
||||
t = jumpf(t, "__bbNullObjEx");
|
||||
t = mem(t);
|
||||
if (g->debug)
|
||||
t = jumpf(t, "__bbNullObjEx");
|
||||
return add(t, iconst(sem_field->offset));
|
||||
}
|
||||
|
||||
VectorVarNode::VectorVarNode(ExprNode* e, ExprSeqNode* es) : expr(e), exprs(es) {}
|
||||
|
||||
VectorVarNode::~VectorVarNode()
|
||||
{
|
||||
delete expr;
|
||||
delete exprs;
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Vector var //
|
||||
////////////////
|
||||
void VectorVarNode::semant(Environ* e)
|
||||
{
|
||||
expr = expr->semant(e);
|
||||
vec_type = expr->sem_type->vectorType();
|
||||
if (!vec_type)
|
||||
ex("Variable must be a Blitz array");
|
||||
if (vec_type->sizes.size() != exprs->size())
|
||||
ex("Incorrect number of subscripts");
|
||||
exprs->semant(e);
|
||||
exprs->castTo(Type::int_type, e);
|
||||
for (int k = 0; k < exprs->size(); ++k) {
|
||||
if (ConstNode* t = exprs->exprs[k]->constNode()) {
|
||||
if (t->intValue() >= vec_type->sizes[k]) {
|
||||
ex("Blitz array subscript out of range");
|
||||
}
|
||||
}
|
||||
}
|
||||
sem_type = vec_type->elementType;
|
||||
}
|
||||
|
||||
TNode* VectorVarNode::translate(Codegen* g)
|
||||
{
|
||||
int sz = 4;
|
||||
TNode* t = 0;
|
||||
for (int k = 0; k < exprs->size(); ++k) {
|
||||
TNode* p;
|
||||
ExprNode* e = exprs->exprs[k];
|
||||
if (ConstNode* t = e->constNode()) {
|
||||
p = iconst(t->intValue() * sz);
|
||||
} else {
|
||||
p = e->translate(g);
|
||||
if (g->debug) {
|
||||
p = jumpge(p, iconst(vec_type->sizes[k]), "__bbVecBoundsEx");
|
||||
}
|
||||
p = mul(p, iconst(sz));
|
||||
}
|
||||
sz = sz * vec_type->sizes[k];
|
||||
t = t ? add(t, p) : p;
|
||||
}
|
||||
return add(t, expr->translate(g));
|
||||
}
|
||||
|
||||
ArrayVarNode::ArrayVarNode(const std::string& i, const std::string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {}
|
||||
|
||||
ArrayVarNode::~ArrayVarNode()
|
||||
{
|
||||
delete exprs;
|
||||
}
|
||||
|
||||
FieldVarNode::FieldVarNode(ExprNode* e, const std::string& i, const std::string& t) : expr(e), ident(i), tag(t) {}
|
||||
|
||||
FieldVarNode::~FieldVarNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
Reference in New Issue
Block a user