compiler: Formatting

This commit is contained in:
Michael Fabian 'Xaymar' Dirks
2019-01-18 17:04:57 +01:00
parent 79cc5fae95
commit c9ff5b8ca4
34 changed files with 7101 additions and 3392 deletions
File diff suppressed because it is too large Load Diff
+211 -101
View File
@@ -7,9 +7,9 @@
*/
#include "../std.h"
#include "../ex.h"
#include "assem_x86.h"
#include "../ex.h"
#include "../std.h"
#include <iomanip>
@@ -21,92 +21,130 @@ static InstMap instMap;
//#define LOG
Assem_x86::Assem_x86( istream &in,Module *mod ):Assem(in,mod){
Assem_x86::Assem_x86(istream& in, Module* mod) : Assem(in, mod)
{
//build instruction map, if not built already.
if (!instMap.size()) {
for (int k = 0; !insts[k].name || insts[k].name[0]; ++k) {
if( insts[k].name ) instMap.insert( InstPair( insts[k].name,&insts[k] ) );
if (insts[k].name)
instMap.insert(InstPair(insts[k].name, &insts[k]));
}
}
}
static int findCC( const string &s ){
if( s=="o" ) return 0;
if( s=="no" ) return 1;
if( s=="b"||s=="c"||s=="nae" ) return 2;
if( s=="ae"||s=="nb"||s=="nc" ) return 3;
if( s=="e"||s=="z" ) return 4;
if( s=="ne"||s=="nz" ) return 5;
if( s=="be"||s=="na" ) return 6;
if( s=="a"||s=="nbe" ) return 7;
if( s=="s" ) return 8;
if( s=="ns" ) return 9;
if( s=="p"||s=="pe" ) return 10;
if( s=="ne"||s=="po" ) return 11;
if( s=="l"||s=="nge" ) return 12;
if( s=="ge"||s=="nl" ) return 13;
if( s=="le"||s=="ng" ) return 14;
if( s=="g"||s=="nle" ) return 15;
static int findCC(const string& s)
{
if (s == "o")
return 0;
if (s == "no")
return 1;
if (s == "b" || s == "c" || s == "nae")
return 2;
if (s == "ae" || s == "nb" || s == "nc")
return 3;
if (s == "e" || s == "z")
return 4;
if (s == "ne" || s == "nz")
return 5;
if (s == "be" || s == "na")
return 6;
if (s == "a" || s == "nbe")
return 7;
if (s == "s")
return 8;
if (s == "ns")
return 9;
if (s == "p" || s == "pe")
return 10;
if (s == "ne" || s == "po")
return 11;
if (s == "l" || s == "nge")
return 12;
if (s == "ge" || s == "nl")
return 13;
if (s == "le" || s == "ng")
return 14;
if (s == "g" || s == "nle")
return 15;
return -1;
}
void Assem_x86::align( int n ){
void Assem_x86::align(int n)
{
int pc = mod->getPC();
int sz = (pc + (n - 1)) / n * n - pc;
while( sz-- ) mod->emit( 0x90 );
while (sz--)
mod->emit(0x90);
}
void Assem_x86::emit( int n ){
void Assem_x86::emit(int n)
{
#ifdef LOG
clog << hex << (int(n) & 0xff) << dec << ' ';
#endif
mod->emit(n);
}
void Assem_x86::emitw( int n ){
void Assem_x86::emitw(int n)
{
emit(n);
emit((n >> 8));
}
void Assem_x86::emitd( int n ){
void Assem_x86::emitd(int n)
{
emitw(n);
emitw(n >> 16);
}
void Assem_x86::emitImm( const Operand &o,int size ){
if( size<4 && o.immLabel.size() ) throw Ex( "immediate value cannot by a label" );
void Assem_x86::emitImm(const Operand& o, int size)
{
if (size < 4 && o.immLabel.size())
throw Ex("immediate value cannot by a label");
switch (size) {
case 1:emit( o.imm );return;
case 2:emitw( o.imm );return;
case 4:a_reloc( o.immLabel );emitd( o.imm );return;
case 1:
emit(o.imm);
return;
case 2:
emitw(o.imm);
return;
case 4:
a_reloc(o.immLabel);
emitd(o.imm);
return;
}
}
void Assem_x86::emitImm( const string &s,int size ){
Operand op(s);op.parse();
if( !(op.mode&IMM) ) throw Ex( "operand must be immediate" );
void Assem_x86::emitImm(const string& s, int size)
{
Operand op(s);
op.parse();
if (!(op.mode & IMM))
throw Ex("operand must be immediate");
emitImm(op, size);
}
void Assem_x86::r_reloc( const string &s ){
if( !s.size() ) return;
void Assem_x86::r_reloc(const string& s)
{
if (!s.size())
return;
mod->addReloc(s.c_str(), mod->getPC(), true);
}
void Assem_x86::a_reloc( const string &s ){
if( !s.size() ) return;
void Assem_x86::a_reloc(const string& s)
{
if (!s.size())
return;
mod->addReloc(s.c_str(), mod->getPC(), false);
}
void Assem_x86::assemInst( const string &name,const string &lhs,const string &rhs ){
void Assem_x86::assemInst(const string& name, const string& lhs, const string& rhs)
{
//parse operands
Operand lop(lhs), rop(rhs);
lop.parse();rop.parse();
lop.parse();
rop.parse();
//find instruction
int cc = -1;
@@ -126,168 +164,240 @@ void Assem_x86::assemInst( const string &name,const string &lhs,const string &rh
}
if (inst) {
if( !(lop.mode&inst->lmode) || !(rop.mode&inst->rmode) ) throw Ex( "illegal addressing mode" );
if (!(lop.mode & inst->lmode) || !(rop.mode & inst->rmode))
throw Ex("illegal addressing mode");
} else {
InstIter it = instMap.find(name);
if( it==instMap.end() ) throw Ex( "unrecognized instruction" );
if (it == instMap.end())
throw Ex("unrecognized instruction");
inst = it->second;
for (;;) {
if( (lop.mode&inst->lmode) && (rop.mode&inst->rmode) ) break;
if( (++inst)->name ) throw Ex( "illegal addressing mode" );
if ((lop.mode & inst->lmode) && (rop.mode & inst->rmode))
break;
if ((++inst)->name)
throw Ex("illegal addressing mode");
}
}
//16/32 bit modifier - NOP for now
if( inst->flags & (O16|O32) ){}
if (inst->flags & (O16 | O32)) {
}
int k, n = inst->bytes[0];
for( k=1;k<n;++k ) emit( inst->bytes[k] );
if( inst->flags&PLUSREG ) emit( inst->bytes[k]+lop.reg );
else if( inst->flags&PLUSCC ) emit( inst->bytes[k]+cc );
else emit( inst->bytes[k] );
for (k = 1; k < n; ++k)
emit(inst->bytes[k]);
if (inst->flags & PLUSREG)
emit(inst->bytes[k] + lop.reg);
else if (inst->flags & PLUSCC)
emit(inst->bytes[k] + cc);
else
emit(inst->bytes[k]);
if (inst->flags & (_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _R)) {
//find the memop;
const Operand &mop=
(inst->rmode&(MEM|MEM8|MEM16|MEM32|R_M|R_M8|R_M16|R_M32))?rop:lop;
const Operand& mop = (inst->rmode & (MEM | MEM8 | MEM16 | MEM32 | R_M | R_M8 | R_M16 | R_M32)) ? rop : lop;
//find the spare field value.
int rm = 0;
switch (inst->flags & (_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _R)) {
case _0:rm=0;break;case _1:rm=1;break;case _2:rm=2;break;case _3:rm=3;break;
case _4:rm=4;break;case _5:rm=5;break;case _6:rm=6;break;case _7:rm=7;break;
case _R:rm=(inst->rmode&(REG8|REG16|REG32))?rop.reg:lop.reg;break;
case _0:
rm = 0;
break;
case _1:
rm = 1;
break;
case _2:
rm = 2;
break;
case _3:
rm = 3;
break;
case _4:
rm = 4;
break;
case _5:
rm = 5;
break;
case _6:
rm = 6;
break;
case _7:
rm = 7;
break;
case _R:
rm = (inst->rmode & (REG8 | REG16 | REG32)) ? rop.reg : lop.reg;
break;
}
rm <<= 3;
if (mop.mode & REG) { //reg
emit(0xc0 | rm | mop.reg);
} else if (mop.baseReg >= 0) { //base, index?
int mod = mop.offset ? 0x40 : 0x00;
if( mop.baseLabel.size() || mop.offset<-128 || mop.offset>127 ) mod=0x80;
if( mop.baseReg==5 && !mod ) mod=0x40;
if (mop.baseLabel.size() || mop.offset < -128 || mop.offset > 127)
mod = 0x80;
if (mop.baseReg == 5 && !mod)
mod = 0x40;
if (mop.indexReg >= 0) { //base, index!
emit(mod | rm | 4);
emit((mop.shift << 6) | (mop.indexReg << 3) | mop.baseReg);
} else { //base, no index!
if( mop.baseReg!=4 ) emit( mod|rm|mop.baseReg);
if (mop.baseReg != 4)
emit(mod | rm | mop.baseReg);
else {
emit( mod|rm|4 );emit( (4<<3)|mop.baseReg );
emit(mod | rm | 4);
emit((4 << 3) | mop.baseReg);
}
}
if( (mod&0xc0)==0x40 ) emit( mop.offset );
if ((mod & 0xc0) == 0x40)
emit(mop.offset);
else if ((mod & 0xc0) == 0x80) {
//reloc
a_reloc( mop.baseLabel );emitd( mop.offset );
a_reloc(mop.baseLabel);
emitd(mop.offset);
}
} else if (mop.indexReg >= 0) { //index, no base!
emit(rm | 4);
emit((mop.shift << 6) | (mop.indexReg << 3) | 5);
//reloc
a_reloc( mop.baseLabel );emitd( mop.offset );
a_reloc(mop.baseLabel);
emitd(mop.offset);
} else { //[disp]
emit(rm | 5);
//reloc
a_reloc( mop.baseLabel );emitd( mop.offset );
a_reloc(mop.baseLabel);
emitd(mop.offset);
}
}
if (inst->flags & RW_RD) {
r_reloc( lop.immLabel );emitd( lop.imm-4 );
r_reloc(lop.immLabel);
emitd(lop.imm - 4);
}
if (inst->flags & IB) {
if( lop.mode&IMM ) emitImm( lop,1 );else emitImm( rop,1 );
if (lop.mode & IMM)
emitImm(lop, 1);
else
emitImm(rop, 1);
} else if (inst->flags & IW) {
if( lop.mode&IMM ) emitImm( lop,2 );else emitImm( rop,2 );
if (lop.mode & IMM)
emitImm(lop, 2);
else
emitImm(rop, 2);
} else if (inst->flags & ID) {
if( lop.mode&IMM ) emitImm( lop,4 );else emitImm( rop,4 );
if (lop.mode & IMM)
emitImm(lop, 4);
else
emitImm(rop, 4);
}
}
void Assem_x86::assemDir( const string &name,const string &op ){
if( !op.size() ) throw Ex( "operand error" );
void Assem_x86::assemDir(const string& name, const string& op)
{
if (!op.size())
throw Ex("operand error");
if (name == ".db") {
if( op[0]!='\"' ) emitImm( op,1 );
if (op[0] != '\"')
emitImm(op, 1);
else {
if( op.size()<2 || op[op.size()-1]!='\"' ) throw Ex( "operand error" );
for( int k=1;k<op.size()-1;++k ) emit( op[k] );
if (op.size() < 2 || op[op.size() - 1] != '\"')
throw Ex("operand error");
for (int k = 1; k < op.size() - 1; ++k)
emit(op[k]);
}
} else if (name == ".dw") {
emitImm(op, 2);
} else if (name == ".dd") {
emitImm(op, 4);
} else if (name == ".align") {
Operand o( op );o.parse();
if( !(o.mode&IMM) ) throw Ex( "operand must be immediate" );
Operand o(op);
o.parse();
if (!(o.mode & IMM))
throw Ex("operand must be immediate");
align(o.imm);
} else {
throw Ex("unrecognized assembler directive");
}
}
void Assem_x86::assemLine( const string &line ){
void Assem_x86::assemLine(const string& line)
{
int i = 0;
string name;
vector<string> ops;
//label?
if (!isspace(line[i])) {
while( !isspace( line[i] ) ) ++i;
while (!isspace(line[i]))
++i;
string lab = line.substr(0, i);
if( !mod->addSymbol( lab.c_str(),mod->getPC() ) ) throw Ex( "duplicate label" );
if (!mod->addSymbol(lab.c_str(), mod->getPC()))
throw Ex("duplicate label");
}
//skip space
while( isspace( line[i] ) && line[i]!='\n' ) ++i;
if( line[i]=='\n' || line[i]==';' ) return;
while (isspace(line[i]) && line[i] != '\n')
++i;
if (line[i] == '\n' || line[i] == ';')
return;
//fetch instruction name
int from=i;for( ++i;!isspace( line[i] );++i ){}
int from = i;
for (++i; !isspace(line[i]); ++i) {
}
name = line.substr(from, i - from);
for (;;) {
//skip space
while( isspace( line[i] ) && line[i]!='\n' ) ++i;
if( line[i]=='\n' || line[i]==';' ) break;
while (isspace(line[i]) && line[i] != '\n')
++i;
if (line[i] == '\n' || line[i] == ';')
break;
int from = i;
if (line[i] == '\"') {
for( ++i;line[i]!='\"' && line[i]!='\n';++i ){}
if( line[i++]!='\"' ) throw Ex( "missing close quote" );
for (++i; line[i] != '\"' && line[i] != '\n'; ++i) {
}
if (line[i++] != '\"')
throw Ex("missing close quote");
} else {
for( ++i;line[i]!=',' && line[i]!=';' && line[i]!='\n';++i ){}
for (++i; line[i] != ',' && line[i] != ';' && line[i] != '\n'; ++i) {
}
}
//back-up over space
while( i && isspace( line[i-1] ) ) --i;
while (i && isspace(line[i - 1]))
--i;
ops.push_back(line.substr(from, i - from));
//skip space
while( isspace( line[i] ) && line[i]!='\n' ) ++i;
if( line[i]=='\n' || line[i]==';' ) break;
while (isspace(line[i]) && line[i] != '\n')
++i;
if (line[i] == '\n' || line[i] == ';')
break;
if( line[i++]!=',' ) throw Ex( "expecting ','" );
if (line[i++] != ',')
throw Ex("expecting ','");
}
//pseudo op?
if (name[0] == '.') {
for( int k=0;k<ops.size();++k ) assemDir( name,ops[k] );
for (int k = 0; k < ops.size(); ++k)
assemDir(name, ops[k]);
return;
}
//normal instruction!
if( ops.size()>2 ) throw Ex( "Too many operands" );
ops.push_back( "" );ops.push_back( "" );
if (ops.size() > 2)
throw Ex("Too many operands");
ops.push_back("");
ops.push_back("");
assemInst(name, ops[0], ops[1]);
}
void Assem_x86::assemble(){
void Assem_x86::assemble()
{
string line;
while (!in.eof()) {
+145 -79
View File
@@ -1,160 +1,226 @@
#include "../std.h"
#include "../ex.h"
#include "operand.h"
#include "../ex.h"
#include "../std.h"
#include "insts.h"
static const char *regs[]={
"al","cl","dl","bl","ah","ch","dh","bh",
"ax","cx","dx","bx","sp","bp","si","di",
"eax","ecx","edx","ebx","esp","ebp","esi","edi"
};
static const char* regs[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", "ax", "cx", "dx", "bx",
"sp", "bp", "si", "di", "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
static void opError(){
static void opError()
{
throw Ex("error in operand");
}
static void sizeError(){
static void sizeError()
{
throw Ex("illegal operand size");
}
Operand::Operand()
:mode(NONE),reg(-1),imm(0),offset(0),baseReg(-1),indexReg(-1),shift(0){
}
Operand::Operand() : mode(NONE), reg(-1), imm(0), offset(0), baseReg(-1), indexReg(-1), shift(0) {}
Operand::Operand( const string &s )
:mode(NONE),reg(-1),imm(0),offset(0),baseReg(-1),indexReg(-1),shift(0),s(s){
}
Operand::Operand(const string& s) : mode(NONE), reg(-1), imm(0), offset(0), baseReg(-1), indexReg(-1), shift(0), s(s) {}
bool Operand::parseSize( int *sz ){
if( !s.size() ) return false;
bool Operand::parseSize(int* sz)
{
if (!s.size())
return false;
if (s.find("byte ") == 0) {
*sz=1;s=s.substr( 5 );
*sz = 1;
s = s.substr(5);
} else if (s.find("word ") == 0) {
*sz=2;s=s.substr( 5 );
*sz = 2;
s = s.substr(5);
} else if (s.find("dword ") == 0) {
*sz=4;s=s.substr( 6 );
}else return false;
*sz = 4;
s = s.substr(6);
} else
return false;
return true;
}
bool Operand::parseChar( char c ){
if( !s.size() || s[0]!=c ) return false;
s=s.substr( 1 );return true;
bool Operand::parseChar(char c)
{
if (!s.size() || s[0] != c)
return false;
s = s.substr(1);
return true;
}
bool Operand::parseReg( int *reg ){
bool Operand::parseReg(int* reg)
{
int i;
for( i=0;i<s.size() && isalpha( s[i] );++i ){}
if( !i ) return false;
for (i = 0; i < s.size() && isalpha(s[i]); ++i) {
}
if (!i)
return false;
string t = s.substr(0, i);
for (int j = 0; j < 24; ++j) {
if( t==regs[j] ){ *reg=j;s=s.substr( i );return true; }
if (t == regs[j]) {
*reg = j;
s = s.substr(i);
return true;
}
}
return false;
}
bool Operand::parseFPReg( int *reg ){
bool Operand::parseFPReg(int* reg)
{
//eg: st(0)
if( s.size()<5 ) return false;
if( s[0]!='s' || s[1]!='t' || s[2]!='(' || s[4]!=')' ) return false;
if( s[3]<'0' || s[3]>'7' ) return false;
*reg=s[3]-'0';s=s.substr( 5 );return true;
if (s.size() < 5)
return false;
if (s[0] != 's' || s[1] != 't' || s[2] != '(' || s[4] != ')')
return false;
if (s[3] < '0' || s[3] > '7')
return false;
*reg = s[3] - '0';
s = s.substr(5);
return true;
}
bool Operand::parseLabel( string *label ){
if( !s.size() || (!isalpha( s[0] ) && s[0]!='_') ) return false;
bool Operand::parseLabel(string* label)
{
if (!s.size() || (!isalpha(s[0]) && s[0] != '_'))
return false;
int i;
for( i=1;i<s.size() && (isalnum( s[i] ) || s[i]=='_');++i ){}
*label=s.substr(0,i);s=s.substr( i );return true;
for (i = 1; i < s.size() && (isalnum(s[i]) || s[i] == '_'); ++i) {
}
*label = s.substr(0, i);
s = s.substr(i);
return true;
}
bool Operand::parseConst( int *iconst ){
bool Operand::parseConst(int* iconst)
{
int i, sgn = s.size() && (s[0] == '-' || s[0] == '+');
for( i=sgn;i<s.size() && isdigit( s[i] );++i ){}
if( i==sgn ) return false;
for (i = sgn; i < s.size() && isdigit(s[i]); ++i) {
}
if (i == sgn)
return false;
int n = atoi(s.c_str());
*iconst=n;s=s.substr( i );return true;
*iconst = n;
s = s.substr(i);
return true;
}
void Operand::parse(){
void Operand::parse()
{
if (!s.size())
return;
if( !s.size() ) return;
int sz;if( !parseSize( &sz ) ) sz=0;
int sz;
if (!parseSize(&sz))
sz = 0;
if (s[0] != '[') {
int r;
if (parseReg(&r)) {
mode = REG | R_M;
if (r < 8) {
if( sz && sz!=1 ) sizeError();
if (sz && sz != 1)
sizeError();
mode |= REG8 | R_M8;
if( r==0 ) mode|=AL;else if( r==1 ) mode|=CL;
if (r == 0)
mode |= AL;
else if (r == 1)
mode |= CL;
} else if (r < 16) {
if( sz && sz!=2 ) sizeError();
if (sz && sz != 2)
sizeError();
mode |= REG16 | R_M16;
if( r==8 ) mode|=AX;else if( r==9 ) mode|=CX;
if (r == 8)
mode |= AX;
else if (r == 9)
mode |= CX;
} else {
if( sz && sz!=4 ) sizeError();
if (sz && sz != 4)
sizeError();
mode |= REG32 | R_M32;
if( r==16 ) mode|=EAX;else if( r==17 ) mode|=ECX;
if (r == 16)
mode |= EAX;
else if (r == 17)
mode |= ECX;
}
reg = r & 7;
} else if (parseFPReg(&r)) {
mode = FPUREG;
if( !r ) mode|=ST0;
if (!r)
mode |= ST0;
reg = r;
} else if (parseLabel(&immLabel)) {
if( sz && sz!=4 ) sizeError();
if (sz && sz != 4)
sizeError();
mode = IMM | IMM32;
} else if (parseConst(&imm)) {
mode = IMM;
if( sz==1 ) mode|=IMM8;
else if( sz==2 ) mode|=IMM16;
else mode|=IMM32;
}else opError();
if( s.size() ) opError();
if (sz == 1)
mode |= IMM8;
else if (sz == 2)
mode |= IMM16;
else
mode |= IMM32;
} else
opError();
if (s.size())
opError();
return;
}
if( s[s.size()-1]!=']' ) opError();
if (s[s.size() - 1] != ']')
opError();
s = s.substr(1, s.size() - 2);
mode = MEM | R_M;
if( sz==1 ) mode|=MEM8|R_M8;
else if( sz==2 ) mode|=MEM16|R_M16;
else mode|=MEM32|R_M32;
if (sz == 1)
mode |= MEM8 | R_M8;
else if (sz == 2)
mode |= MEM16 | R_M16;
else
mode |= MEM32 | R_M32;
for (;;) {
int n;string l;
int n;
string l;
if (parseReg(&n)) {
if( n<16 ) throw Ex( "register must be 32 bit" );
if (n < 16)
throw Ex("register must be 32 bit");
n &= 7;
if (parseChar('*')) {
if( n==4 ) break; //esp cannot be index reg!
if( indexReg>=0 ) break;
if( parseChar( '1' ) ) shift=0;
else if( parseChar( '2' ) ) shift=1;
else if( parseChar( '4' ) ) shift=2;
else if( parseChar( '8' ) ) shift=3;
else break;
if (n == 4)
break; //esp cannot be index reg!
if (indexReg >= 0)
break;
if (parseChar('1'))
shift = 0;
else if (parseChar('2'))
shift = 1;
else if (parseChar('4'))
shift = 2;
else if (parseChar('8'))
shift = 3;
else
break;
indexReg = n;
} else {
if( baseReg<0 ) baseReg=n;
else if( indexReg<0 ){ indexReg=n; }
else break;
if (baseReg < 0)
baseReg = n;
else if (indexReg < 0) {
indexReg = n;
} else
break;
}
} else if (parseLabel(&l)) {
if( baseLabel.size() ) opError();
if (baseLabel.size())
opError();
baseLabel = l;
} else if (parseConst(&n)) {
offset += n;
}else break;
if( !s.size() ) return;
} else
break;
if (!s.size())
return;
}
opError();
}
+52 -11
View File
@@ -5,23 +5,60 @@
#include "std.hpp"
enum {
IR_JUMP,IR_JUMPT,IR_JUMPF,IR_JUMPGE,
IR_JUMP,
IR_JUMPT,
IR_JUMPF,
IR_JUMPGE,
IR_SEQ,IR_MOVE,IR_MEM,IR_LOCAL,IR_GLOBAL,IR_ARG,IR_CONST,
IR_SEQ,
IR_MOVE,
IR_MEM,
IR_LOCAL,
IR_GLOBAL,
IR_ARG,
IR_CONST,
IR_JSR,IR_RET,IR_AND,IR_OR,IR_XOR,IR_SHL,IR_SHR,IR_SAR,
IR_JSR,
IR_RET,
IR_AND,
IR_OR,
IR_XOR,
IR_SHL,
IR_SHR,
IR_SAR,
IR_CALL,IR_RETURN,IR_CAST,
IR_NEG,IR_ADD,IR_SUB,IR_MUL,IR_DIV,
IR_SETEQ,IR_SETNE,IR_SETLT,IR_SETGT,IR_SETLE,IR_SETGE,
IR_CALL,
IR_RETURN,
IR_CAST,
IR_NEG,
IR_ADD,
IR_SUB,
IR_MUL,
IR_DIV,
IR_SETEQ,
IR_SETNE,
IR_SETLT,
IR_SETGT,
IR_SETLE,
IR_SETGE,
IR_FCALL,IR_FRETURN,IR_FCAST,
IR_FNEG,IR_FADD,IR_FSUB,IR_FMUL,IR_FDIV,
IR_FSETEQ,IR_FSETNE,IR_FSETLT,IR_FSETGT,IR_FSETLE,IR_FSETGE,
IR_FCALL,
IR_FRETURN,
IR_FCAST,
IR_FNEG,
IR_FADD,
IR_FSUB,
IR_FMUL,
IR_FDIV,
IR_FSETEQ,
IR_FSETNE,
IR_FSETLT,
IR_FSETGT,
IR_FSETLE,
IR_FSETGE,
};
struct TNode {
int op; //opcode
TNode *l, *r; //args
int iconst; //for CONST type_int
@@ -30,7 +67,11 @@ struct TNode{
TNode(int op, TNode* l = 0, TNode* r = 0) : op(op), l(l), r(r), iconst(0) {}
TNode(int op, TNode* l, TNode* r, int i) : op(op), l(l), r(r), iconst(i) {}
TNode(int op, TNode* l, TNode* r, const string& s) : op(op), l(l), r(r), iconst(0), sconst(s) {}
~TNode(){ delete l;delete r; }
~TNode()
{
delete l;
delete r;
}
void log();
};
+242 -97
View File
@@ -1,76 +1,97 @@
#include "../std.h"
#include "codegen_x86.h"
#include "../std.h"
#include "tile.h"
//#define NOOPTS
Codegen_x86::Codegen_x86( ostream &out,bool debug ):Codegen( out,debug ),inCode(false){
}
Codegen_x86::Codegen_x86(ostream& out, bool debug) : Codegen(out, debug), inCode(false) {}
static string itoa_sgn(int n){
static string itoa_sgn(int n)
{
return n ? (n > 0 ? "+" + itoa(n) : itoa(n)) : "";
}
static bool isRelop( int op ){
static bool isRelop(int op)
{
return op == IR_SETEQ || op == IR_SETNE || op == IR_SETLT || op == IR_SETGT || op == IR_SETLE || op == IR_SETGE;
}
static bool nodesEqual( TNode *t1,TNode *t2 ){
if( t1->op!=t2->op ||
t1->iconst!=t2->iconst ||
t1->sconst!=t2->sconst ) return false;
static bool nodesEqual(TNode* t1, TNode* t2)
{
if (t1->op != t2->op || t1->iconst != t2->iconst || t1->sconst != t2->sconst)
return false;
if (t1->l) {
if( !t2->l || !nodesEqual( t1->l,t2->l ) ) return false;
}else if( t2->l ) return false;
if (!t2->l || !nodesEqual(t1->l, t2->l))
return false;
} else if (t2->l)
return false;
if (t1->r) {
if( !t2->r || !nodesEqual( t1->r,t2->r ) ) return false;
}else if( t2->r ) return false;
if (!t2->r || !nodesEqual(t1->r, t2->r))
return false;
} else if (t2->r)
return false;
return true;
}
static bool getShift( int n,int &shift ){
static bool getShift(int n, int& shift)
{
#ifdef NOOPTS
return false;
#endif
for (shift = 0; shift < 32; ++shift) {
if( (1<<shift)==n ) return true;
if ((1 << shift) == n)
return true;
}
return false;
}
static bool matchMEM( TNode *t,string &s ){
static bool matchMEM(TNode* t, string& s)
{
#ifdef NOOPTS
return false;
#endif
if( t->op!=IR_MEM ) return false;
if (t->op != IR_MEM)
return false;
t = t->l;
switch (t->op) {
case IR_GLOBAL:s="["+t->sconst+"]";return true;
case IR_LOCAL:s="[ebp"+itoa_sgn(t->iconst)+"]";return true;
case IR_ARG:s="[esp"+itoa_sgn(t->iconst)+"]";return true;
case IR_GLOBAL:
s = "[" + t->sconst + "]";
return true;
case IR_LOCAL:
s = "[ebp" + itoa_sgn(t->iconst) + "]";
return true;
case IR_ARG:
s = "[esp" + itoa_sgn(t->iconst) + "]";
return true;
}
return false;
}
static bool matchCONST( TNode *t,string &s ){
static bool matchCONST(TNode* t, string& s)
{
#ifdef NOOPTS
return false;
#endif
switch (t->op) {
case IR_CONST:s=itoa( t->iconst );return true;
case IR_GLOBAL:s=t->sconst;return true;
case IR_CONST:
s = itoa(t->iconst);
return true;
case IR_GLOBAL:
s = t->sconst;
return true;
}
return false;
}
static bool matchMEMCONST( TNode *t,string &s ){
static bool matchMEMCONST(TNode* t, string& s)
{
#ifdef NOOPTS
return false;
#endif
@@ -78,16 +99,29 @@ static bool matchMEMCONST( TNode *t,string &s ){
return matchMEM(t, s) || matchCONST(t, s);
}
Tile *Codegen_x86::genCompare( TNode *t,string &func,bool negate ){
Tile* Codegen_x86::genCompare(TNode* t, string& func, bool negate)
{
switch (t->op) {
case IR_SETEQ:func=negate ? "nz" : "z";break;
case IR_SETNE:func=negate ? "z" : "nz";break;
case IR_SETLT:func=negate ? "ge" : "l";break;
case IR_SETGT:func=negate ? "le" : "g";break;
case IR_SETLE:func=negate ? "g" : "le";break;
case IR_SETGE:func=negate ? "l" : "ge";break;
default:return 0;
case IR_SETEQ:
func = negate ? "nz" : "z";
break;
case IR_SETNE:
func = negate ? "z" : "nz";
break;
case IR_SETLT:
func = negate ? "ge" : "l";
break;
case IR_SETGT:
func = negate ? "le" : "g";
break;
case IR_SETLE:
func = negate ? "g" : "le";
break;
case IR_SETGE:
func = negate ? "l" : "ge";
break;
default:
return 0;
}
string q, m, c;
@@ -97,13 +131,17 @@ Tile *Codegen_x86::genCompare( TNode *t,string &func,bool negate ){
if (matchCONST(t->r, c)) {
q = "\tcmp\t" + m + "," + c + "\n";
} else {
q="\tcmp\t"+m+",%l\n";ql=t->r;
q = "\tcmp\t" + m + ",%l\n";
ql = t->r;
}
} else {
if (matchMEMCONST(t->r, m)) {
q="\tcmp\t%l,"+m+"\n";ql=t->l;
q = "\tcmp\t%l," + m + "\n";
ql = t->l;
} else {
q="\tcmp\t%l,%r\n";ql=t->l;qr=t->r;
q = "\tcmp\t%l,%r\n";
ql = t->l;
qr = t->r;
}
}
@@ -113,28 +151,40 @@ Tile *Codegen_x86::genCompare( TNode *t,string &func,bool negate ){
////////////////////////////////////////////////
// Integer expressions returned in a register //
////////////////////////////////////////////////
Tile *Codegen_x86::munchUnary( TNode *t ){
Tile* Codegen_x86::munchUnary(TNode* t)
{
string s;
switch (t->op) {
case IR_NEG:s="\tneg\t%l\n";break;
default:return 0;
case IR_NEG:
s = "\tneg\t%l\n";
break;
default:
return 0;
}
return new Tile(s, munchReg(t->l));
}
Tile *Codegen_x86::munchLogical( TNode *t ){
Tile* Codegen_x86::munchLogical(TNode* t)
{
string s;
switch (t->op) {
case IR_AND:s="\tand\t%l,%r\n";break;
case IR_OR:s="\tor\t%l,%r\n";break;
case IR_XOR:s="\txor\t%l,%r\n";break;
default:return 0;
case IR_AND:
s = "\tand\t%l,%r\n";
break;
case IR_OR:
s = "\tor\t%l,%r\n";
break;
case IR_XOR:
s = "\txor\t%l,%r\n";
break;
default:
return 0;
}
return new Tile(s, munchReg(t->l), munchReg(t->r));
}
Tile *Codegen_x86::munchArith( TNode *t ){
Tile* Codegen_x86::munchArith(TNode* t)
{
if (t->op == IR_DIV) {
int shift;
if (t->r->op == IR_CONST) {
@@ -143,7 +193,9 @@ Tile *Codegen_x86::munchArith( TNode *t ){
}
}
Tile* q = new Tile("\tcdq\n\tidiv\tecx\n", munchReg(t->l), munchReg(t->r));
q->want_l=EAX;q->want_r=ECX;q->hits=1<<EDX;
q->want_l = EAX;
q->want_r = ECX;
q->hits = 1 << EDX;
return q;
}
@@ -162,10 +214,17 @@ Tile *Codegen_x86::munchArith( TNode *t ){
string s, op;
switch (t->op) {
case IR_ADD:op="\tadd\t";break;
case IR_SUB:op="\tsub\t";break;
case IR_MUL:op="\timul\t";break;
default:return 0;
case IR_ADD:
op = "\tadd\t";
break;
case IR_SUB:
op = "\tsub\t";
break;
case IR_MUL:
op = "\timul\t";
break;
default:
return 0;
}
if (matchMEMCONST(t->r, s)) {
@@ -177,13 +236,21 @@ Tile *Codegen_x86::munchArith( TNode *t ){
return new Tile(op + "%l,%r\n", munchReg(t->l), munchReg(t->r));
}
Tile *Codegen_x86::munchShift( TNode *t ){
Tile* Codegen_x86::munchShift(TNode* t)
{
string s, op;
switch (t->op) {
case IR_SHL:op="\tshl\t";break;
case IR_SHR:op="\tshr\t";break;
case IR_SAR:op="\tsar\t";break;
default:return 0;
case IR_SHL:
op = "\tshl\t";
break;
case IR_SHR:
op = "\tshr\t";
break;
case IR_SAR:
op = "\tsar\t";
break;
default:
return 0;
}
if (matchCONST(t->r, s)) {
@@ -191,10 +258,12 @@ Tile *Codegen_x86::munchShift( TNode *t ){
}
Tile* q = new Tile(op + "%l,cl\n", munchReg(t->l), munchReg(t->r));
q->want_r=ECX;return q;
q->want_r = ECX;
return q;
}
Tile *Codegen_x86::munchRelop( TNode *t ){
Tile* Codegen_x86::munchRelop(TNode* t)
{
string func;
Tile* q = genCompare(t, func, false);
@@ -206,37 +275,73 @@ Tile *Codegen_x86::munchRelop( TNode *t ){
////////////////////////////////////////////////
// Float expressions returned on the FP stack //
////////////////////////////////////////////////
Tile *Codegen_x86::munchFPUnary( TNode *t ){
Tile* Codegen_x86::munchFPUnary(TNode* t)
{
string s;
switch (t->op) {
case IR_FNEG:s="\tfchs\n";break;
default:return 0;
case IR_FNEG:
s = "\tfchs\n";
break;
default:
return 0;
}
return new Tile(s, munchFP(t->l));
}
Tile *Codegen_x86::munchFPArith( TNode *t ){
Tile* Codegen_x86::munchFPArith(TNode* t)
{
string s, s2;
switch (t->op) {
case IR_FADD:s="\tfaddp\tst(1)\n";break;
case IR_FMUL:s="\tfmulp\tst(1)\n";break;
case IR_FSUB:s="\tfsubrp\tst(1)\n";s2="\tfsubp\tst(1)\n";break;
case IR_FDIV:s="\tfdivrp\tst(1)\n";s2="\tfdivp\tst(1)\n";break;
default:return 0;
case IR_FADD:
s = "\tfaddp\tst(1)\n";
break;
case IR_FMUL:
s = "\tfmulp\tst(1)\n";
break;
case IR_FSUB:
s = "\tfsubrp\tst(1)\n";
s2 = "\tfsubp\tst(1)\n";
break;
case IR_FDIV:
s = "\tfdivrp\tst(1)\n";
s2 = "\tfdivp\tst(1)\n";
break;
default:
return 0;
}
return new Tile(s, s2, munchFP(t->l), munchFP(t->r));
}
Tile *Codegen_x86::munchFPRelop( TNode *t ){
Tile* Codegen_x86::munchFPRelop(TNode* t)
{
string s, s2;
switch (t->op) {
case IR_FSETEQ:s="z";s2="z";break;
case IR_FSETNE:s="nz";s2="nz";break;
case IR_FSETLT:s="b";s2="a";break;
case IR_FSETGT:s="a";s2="b";break;
case IR_FSETLE:s="be";s2="ae";break;
case IR_FSETGE:s="ae";s2="be";break;
default:return 0;
case IR_FSETEQ:
s = "z";
s2 = "z";
break;
case IR_FSETNE:
s = "nz";
s2 = "nz";
break;
case IR_FSETLT:
s = "b";
s2 = "a";
break;
case IR_FSETGT:
s = "a";
s2 = "b";
break;
case IR_FSETLE:
s = "be";
s2 = "ae";
break;
case IR_FSETGE:
s = "ae";
s2 = "be";
break;
default:
return 0;
}
s = "\tfucompp\n\tfnstsw\tax\n\tsahf\n\tset" + s + "\tal\n\tmovzx\t%l,al\n";
s2 = "\tfucompp\n\tfnstsw\tax\n\tsahf\n\tset" + s2 + "\tal\n\tmovzx\t%l,al\n";
@@ -248,7 +353,8 @@ Tile *Codegen_x86::munchFPRelop( TNode *t ){
///////////////////////////
// Generic Call handling //
///////////////////////////
Tile *Codegen_x86::munchCall( TNode *t ){
Tile* Codegen_x86::munchCall(TNode* t)
{
Tile* q;
if (t->l->op == IR_GLOBAL) {
q = new Tile("\tcall\t" + t->l->sconst + "\n", t->r ? munchReg(t->r) : 0);
@@ -264,8 +370,10 @@ Tile *Codegen_x86::munchCall( TNode *t ){
/////////////////////////////
// munch and dicard result //
/////////////////////////////
Tile *Codegen_x86::munch( TNode *t ){
if( !t ) return 0;
Tile* Codegen_x86::munch(TNode* t)
{
if (!t)
return 0;
Tile* q = 0;
string s;
switch (t->op) {
@@ -276,7 +384,8 @@ Tile *Codegen_x86::munch( TNode *t ){
q = new Tile("\tret\n");
break;
case IR_RETURN:
q=munchReg( t->l );q->want_l=EAX;
q = munchReg(t->l);
q->want_l = EAX;
s = "\tjmp\t" + t->sconst + '\n';
q = new Tile(s, q);
break;
@@ -318,13 +427,19 @@ Tile *Codegen_x86::munch( TNode *t ){
q = new Tile("\tmov\t" + s + "," + c + "\n");
} else if (t->l->op == IR_ADD || t->l->op == IR_SUB) {
TNode* p = 0;
if( nodesEqual( t->l->l,t->r ) ) p=t->l->r;
else if( t->l->op==IR_ADD && nodesEqual( t->l->r,t->r ) ) p=t->l->l;
if (nodesEqual(t->l->l, t->r))
p = t->l->r;
else if (t->l->op == IR_ADD && nodesEqual(t->l->r, t->r))
p = t->l->l;
if (p) {
string c, op;
switch (t->l->op) {
case IR_ADD:op="\tadd\t";break;
case IR_SUB:op="\tsub\t";break;
case IR_ADD:
op = "\tadd\t";
break;
case IR_SUB:
op = "\tsub\t";
break;
}
if (matchCONST(p, c)) {
q = new Tile(op + s + "," + c + "\n");
@@ -333,19 +448,23 @@ Tile *Codegen_x86::munch( TNode *t ){
}
}
}
if( !q ) q=new Tile( "\tmov\t"+s+",%l\n",munchReg( t->l ) );
if (!q)
q = new Tile("\tmov\t" + s + ",%l\n", munchReg(t->l));
}
break;
}
if( !q ) q=munchReg( t );
if (!q)
q = munchReg(t);
return q;
}
///////////////////////////////////////////
// munch and return result in a register //
///////////////////////////////////////////
Tile *Codegen_x86::munchReg( TNode *t ){
if( !t ) return 0;
Tile* Codegen_x86::munchReg(TNode* t)
{
if (!t)
return 0;
string s;
Tile* q = 0;
@@ -401,23 +520,42 @@ Tile *Codegen_x86::munchReg( TNode *t ){
case IR_NEG:
q = munchUnary(t);
break;
case IR_AND:case IR_OR:case IR_XOR:
case IR_AND:
case IR_OR:
case IR_XOR:
q = munchLogical(t);
break;
case IR_ADD:case IR_SUB:case IR_MUL:case IR_DIV:
case IR_ADD:
case IR_SUB:
case IR_MUL:
case IR_DIV:
q = munchArith(t);
break;
case IR_SHL:case IR_SHR:case IR_SAR:
case IR_SHL:
case IR_SHR:
case IR_SAR:
q = munchShift(t);
break;
case IR_SETEQ:case IR_SETNE:case IR_SETLT:case IR_SETGT:case IR_SETLE:case IR_SETGE:
case IR_SETEQ:
case IR_SETNE:
case IR_SETLT:
case IR_SETGT:
case IR_SETLE:
case IR_SETGE:
q = munchRelop(t);
break;
case IR_FSETEQ:case IR_FSETNE:case IR_FSETLT:case IR_FSETGT:case IR_FSETLE:case IR_FSETGE:
case IR_FSETEQ:
case IR_FSETNE:
case IR_FSETLT:
case IR_FSETGT:
case IR_FSETLE:
case IR_FSETGE:
q = munchFPRelop(t);
break;
default:
q=munchFP( t );if( !q ) return 0;
q = munchFP(t);
if (!q)
return 0;
s = "\tpush\t%l\n\tfstp\t[esp]\n\tpop\t%l\n";
q = new Tile(s, q);
}
@@ -427,8 +565,10 @@ Tile *Codegen_x86::munchReg( TNode *t ){
/////////////////////////////////////////
// munch and return result on FP stack //
/////////////////////////////////////////
Tile *Codegen_x86::munchFP( TNode *t ){
if( !t ) return 0;
Tile* Codegen_x86::munchFP(TNode* t)
{
if (!t)
return 0;
string s;
Tile* q = 0;
@@ -444,11 +584,16 @@ Tile *Codegen_x86::munchFP( TNode *t ){
case IR_FNEG:
q = munchFPUnary(t);
break;
case IR_FADD:case IR_FSUB:case IR_FMUL:case IR_FDIV:
case IR_FADD:
case IR_FSUB:
case IR_FMUL:
case IR_FDIV:
q = munchFPArith(t);
break;
default:
q=munchReg( t );if( !q ) return 0;
q = munchReg(t);
if (!q)
return 0;
s = "\tpush\t%l\n\tfld\t[esp]\n\tpop\t%l\n";
q = new Tile(s, q);
}
+138 -71
View File
@@ -1,13 +1,12 @@
#include "tile.h"
#include "../std.h"
#include "codegen_x86.h"
#include "tile.h"
//reduce to 3 for stress test
static const int NUM_REGS = 6;
static const string regs[] =
{ "???","eax","ecx","edx","edi","esi","ebx" };
static const string regs[] = {"???", "eax", "ecx", "edx", "edi", "esi", "ebx"};
//array of 'used' flags
static bool regUsed[NUM_REGS + 1];
@@ -21,85 +20,117 @@ static vector<string> codeFrags, dataFrags;
//name of function
static string funcLabel;
static void resetRegs() {
for (int n = 1; n <= NUM_REGS; ++n) regUsed[n] = false;
static void resetRegs()
{
for (int n = 1; n <= NUM_REGS; ++n)
regUsed[n] = false;
}
static int allocReg(int n) {
static int allocReg(int n)
{
if (!n || regUsed[n]) {
for (n = NUM_REGS; n >= 1 && regUsed[n]; --n) {}
if (!n) return 0;
for (n = NUM_REGS; n >= 1 && regUsed[n]; --n) {
}
if (!n)
return 0;
}
regUsed[n] = true;
return n;
}
static void freeReg(int n) {
static void freeReg(int n)
{
regUsed[n] = false;
}
static void pushReg(int n) {
static void pushReg(int n)
{
frameSize += 4;
if (frameSize > maxFrameSize) maxFrameSize = frameSize;
if (frameSize > maxFrameSize)
maxFrameSize = frameSize;
char buff[32];
_itoa(frameSize, buff, 10);
string s = "\tmov\t[ebp-"; s += buff; s += "],"; s += regs[n]; s += '\n';
string s = "\tmov\t[ebp-";
s += buff;
s += "],";
s += regs[n];
s += '\n';
codeFrags.push_back(s);
}
static void popReg(int n) {
char buff[32]; _itoa(frameSize, buff, 10);
string s = "\tmov\t"; s += regs[n]; s += ",[ebp-"; s += buff; s += "]\n";
static void popReg(int n)
{
char buff[32];
_itoa(frameSize, buff, 10);
string s = "\tmov\t";
s += regs[n];
s += ",[ebp-";
s += buff;
s += "]\n";
codeFrags.push_back(s);
frameSize -= 4;
}
static void moveReg(int d, int s) {
static void moveReg(int d, int s)
{
string t = "\tmov\t" + regs[d] + ',' + regs[s] + '\n';
codeFrags.push_back(t);
}
static void swapRegs(int d, int s) {
static void swapRegs(int d, int s)
{
string t = "\txchg\t" + regs[d] + ',' + regs[s] + '\n';
codeFrags.push_back(t);
}
Tile::Tile(const string& a, Tile* l, Tile* r)
:assem(a), l(l), r(r), want_l(0), want_r(0), hits(0), need(0), argFrame(0) {
}
: assem(a), l(l), r(r), want_l(0), want_r(0), hits(0), need(0), argFrame(0)
{}
Tile::Tile(const string& a, const string& a2, Tile* l, Tile* r)
: assem(a), assem2(a2), l(l), r(r), want_l(0), want_r(0), hits(0), need(0), argFrame(0) {
: assem(a), assem2(a2), l(l), r(r), want_l(0), want_r(0), hits(0), need(0), argFrame(0)
{}
Tile::~Tile()
{
delete l;
delete r;
}
Tile::~Tile() {
delete l; delete r;
}
void Tile::label() {
void Tile::label()
{
if (!l) {
need = 1;
} else if (!r) {
l->label();
need = l->need;
} else {
l->label(); r->label();
if (l->need == r->need) need = l->need + 1;
else if (l->need > r->need) need = l->need;
else need = r->need;
l->label();
r->label();
if (l->need == r->need)
need = l->need + 1;
else if (l->need > r->need)
need = l->need;
else
need = r->need;
}
}
int Tile::eval(int want) {
int Tile::eval(int want)
{
//save any hit registers
int spill = hits;
if (want_l) spill |= 1 << want_l;
if (want_r) spill |= 1 << want_r;
if (want_l)
spill |= 1 << want_l;
if (want_r)
spill |= 1 << want_r;
if (spill) {
for (int n = 1; n <= NUM_REGS; ++n) {
if (spill & (1 << n)) {
if (regUsed[n]) pushReg(n);
else spill &= ~(1 << n);
if (regUsed[n])
pushReg(n);
else
spill &= ~(1 << n);
}
}
}
@@ -110,7 +141,8 @@ int Tile::eval(int want) {
}
int got_l = 0, got_r = 0;
if (want_l) want = want_l;
if (want_l)
want = want_l;
string* as = &assem;
@@ -121,37 +153,49 @@ int Tile::eval(int want) {
} else {
if (l->need >= NUM_REGS && r->need >= NUM_REGS) {
got_r = r->eval(0);
pushReg(got_r); freeReg(got_r);
pushReg(got_r);
freeReg(got_r);
got_l = l->eval(want);
got_r = allocReg(want_r); popReg(got_r);
got_r = allocReg(want_r);
popReg(got_r);
} else if (r->need > l->need) {
got_r = r->eval(want_r);
got_l = l->eval(want);
} else {
got_l = l->eval(want);
got_r = r->eval(want_r);
if (assem2.size()) as = &assem2;
if (assem2.size())
as = &assem2;
}
if (want_l == got_r || want_r == got_l) {
swapRegs(got_l, got_r);
int t = got_l; got_l = got_r; got_r = t;
int t = got_l;
got_l = got_r;
got_r = t;
}
}
if (!want_l) want_l = got_l;
else if (want_l != got_l) moveReg(want_l, got_l);
if (!want_l)
want_l = got_l;
else if (want_l != got_l)
moveReg(want_l, got_l);
if (!want_r) want_r = got_r;
else if (want_r != got_r) moveReg(want_r, got_r);
if (!want_r)
want_r = got_r;
else if (want_r != got_r)
moveReg(want_r, got_r);
int i;
while ((i = as->find("%l")) != string::npos) as->replace(i, 2, regs[want_l]);
while ((i = as->find("%r")) != string::npos) as->replace(i, 2, regs[want_r]);
while ((i = as->find("%l")) != string::npos)
as->replace(i, 2, regs[want_l]);
while ((i = as->find("%r")) != string::npos)
as->replace(i, 2, regs[want_r]);
codeFrags.push_back(*as);
freeReg(got_r);
if (want_l != got_l) moveReg(got_l, want_l);
if (want_l != got_l)
moveReg(got_l, want_l);
//cleanup argFrame
if (argFrame) {
@@ -162,26 +206,31 @@ int Tile::eval(int want) {
//restore spilled regs
if (spill) {
for (int n = NUM_REGS; n >= 1; --n) {
if (spill&(1 << n)) popReg(n);
if (spill & (1 << n))
popReg(n);
}
}
return got_l;
}
void Codegen_x86::flush() {
void Codegen_x86::flush()
{
vector<string>::iterator it;
for (it = dataFrags.begin(); it != dataFrags.end(); ++it) out << *it;
for (it = dataFrags.begin(); it != dataFrags.end(); ++it)
out << *it;
dataFrags.clear();
}
void Codegen_x86::enter(const string &l, int frameSize) {
void Codegen_x86::enter(const string& l, int frameSize)
{
inCode = true;
::frameSize = maxFrameSize = frameSize;
codeFrags.clear(); funcLabel = l;
codeFrags.clear();
funcLabel = l;
}
void Codegen_x86::code(TNode *stmt) {
void Codegen_x86::code(TNode* stmt)
{
resetRegs();
Tile* q = munch(stmt);
q->label();
@@ -190,12 +239,15 @@ void Codegen_x86::code(TNode *stmt) {
delete stmt;
}
static string fixEsp(int esp_off) {
if (esp_off < 0) return "\tsub\tesp," + itoa(-esp_off) + "\n";
static string fixEsp(int esp_off)
{
if (esp_off < 0)
return "\tsub\tesp," + itoa(-esp_off) + "\n";
return "\tadd\tesp," + itoa(esp_off) + "\n";
}
void Codegen_x86::leave(TNode *cleanup, int pop_sz) {
void Codegen_x86::leave(TNode* cleanup, int pop_sz)
{
if (cleanup) {
resetRegs();
allocReg(EAX);
@@ -207,14 +259,16 @@ void Codegen_x86::leave(TNode *cleanup, int pop_sz) {
out << "\t.align\t16\n";
if (funcLabel.size()) out << funcLabel << '\n';
if (funcLabel.size())
out << funcLabel << '\n';
out << "\tpush\tebx\n";
out << "\tpush\tesi\n";
out << "\tpush\tedi\n";
out << "\tpush\tebp\n";
out << "\tmov\tebp,esp\n";
if (maxFrameSize) out << "\tsub\tesp," << maxFrameSize << '\n';
if (maxFrameSize)
out << "\tsub\tesp," << maxFrameSize << '\n';
int esp_off = 0;
vector<string>::iterator it = codeFrags.begin();
@@ -233,7 +287,8 @@ void Codegen_x86::leave(TNode *cleanup, int pop_sz) {
out << *it;
}
}
if (esp_off) out << fixEsp(esp_off);
if (esp_off)
out << fixEsp(esp_off);
out << "\tmov\tesp,ebp\n";
out << "\tpop\tebp\n";
@@ -246,29 +301,41 @@ void Codegen_x86::leave(TNode *cleanup, int pop_sz) {
inCode = false;
}
void Codegen_x86::label(const string &l) {
void Codegen_x86::label(const string& l)
{
string t = l + '\n';
if (inCode) codeFrags.push_back(t);
else dataFrags.push_back(t);
if (inCode)
codeFrags.push_back(t);
else
dataFrags.push_back(t);
}
void Codegen_x86::align_data(int n) {
char buff[32]; _itoa(n, buff, 10);
void Codegen_x86::align_data(int n)
{
char buff[32];
_itoa(n, buff, 10);
dataFrags.push_back(string("\t.align\t") + buff + '\n');
}
void Codegen_x86::i_data(int i, const string &l) {
if (l.size()) dataFrags.push_back(l);
char buff[32]; _itoa(i, buff, 10);
void Codegen_x86::i_data(int i, const string& l)
{
if (l.size())
dataFrags.push_back(l);
char buff[32];
_itoa(i, buff, 10);
dataFrags.push_back(string("\t.dd\t") + buff + '\n');
}
void Codegen_x86::s_data(const string &s, const string &l) {
if (l.size()) dataFrags.push_back(l);
void Codegen_x86::s_data(const string& s, const string& l)
{
if (l.size())
dataFrags.push_back(l);
dataFrags.push_back(string("\t.db\t\"") + s + "\",0\n");
}
void Codegen_x86::p_data(const string &p, const string &l) {
if (l.size()) dataFrags.push_back(l);
void Codegen_x86::p_data(const string& p, const string& l)
{
if (l.size())
dataFrags.push_back(l);
dataFrags.push_back(string("\t.dd\t") + p + '\n');
}
+17 -13
View File
@@ -1,35 +1,39 @@
#include "std.hpp"
#include "decl.hpp"
#include "std.hpp"
#include "type.hpp"
Decl::~Decl(){
}
Decl::~Decl() {}
DeclSeq::DeclSeq(){
}
DeclSeq::DeclSeq() {}
void Decl::getName( char *buff ){
void Decl::getName(char* buff)
{
int sz = name.size();
memcpy(buff, name.data(), sz);
buff[sz] = 0;
}
DeclSeq::~DeclSeq(){
for( ;decls.size();decls.pop_back() ) delete decls.back();
DeclSeq::~DeclSeq()
{
for (; decls.size(); decls.pop_back())
delete decls.back();
}
Decl *DeclSeq::findDecl( const string &s ){
Decl* DeclSeq::findDecl(const string& s)
{
vector<Decl*>::iterator it;
for (it = decls.begin(); it != decls.end(); ++it) {
if( (*it)->name==s ) return *it;
if ((*it)->name == s)
return *it;
}
return 0;
}
Decl *DeclSeq::insertDecl( const string &s,Type *t,int kind,ConstType *d ){
if( findDecl( s ) ) return 0;
Decl* DeclSeq::insertDecl(const string& s, Type* t, int kind, ConstType* d)
{
if (findDecl(s))
return 0;
decls.push_back(new Decl(s, t, kind, d));
return decls.back();
}
+11 -3
View File
@@ -3,8 +3,13 @@
#define DECL_H
enum {
DECL_FUNC=1,DECL_ARRAY=2,DECL_STRUCT=4, //NOT vars
DECL_GLOBAL=8,DECL_LOCAL=16,DECL_PARAM=32,DECL_FIELD=64 //ARE vars
DECL_FUNC = 1,
DECL_ARRAY = 2,
DECL_STRUCT = 4, //NOT vars
DECL_GLOBAL = 8,
DECL_LOCAL = 16,
DECL_PARAM = 32,
DECL_FIELD = 64 //ARE vars
};
struct Type;
@@ -27,7 +32,10 @@ struct DeclSeq{
~DeclSeq();
Decl* findDecl(const string& s);
Decl* insertDecl(const string& s, Type* t, int kind, ConstType* d = 0);
int size(){ return decls.size(); }
int size()
{
return decls.size();
}
};
#endif
+147 -78
View File
@@ -1,45 +1,65 @@
#include "std.hpp"
#include "nodes.hpp"
#include "std.hpp"
//////////////////////////////
// Sequence of declarations //
//////////////////////////////
void DeclSeqNode::proto(DeclSeq *d, Environ *e) {
void DeclSeqNode::proto(DeclSeq* d, Environ* e)
{
for (size_t k = 0; k < decls.size(); ++k) {
try { decls[k]->proto(d, e); } catch (Ex &x) {
if (x.pos < 0) x.pos = decls[k]->pos;
if (!x.file.size()) x.file = decls[k]->file;
try {
decls[k]->proto(d, e);
} catch (Ex& x) {
if (x.pos < 0)
x.pos = decls[k]->pos;
if (!x.file.size())
x.file = decls[k]->file;
throw;
}
}
}
void DeclSeqNode::semant(Environ *e) {
void DeclSeqNode::semant(Environ* e)
{
for (size_t k = 0; k < decls.size(); ++k) {
try { decls[k]->semant(e); } catch (Ex &x) {
if (x.pos < 0) x.pos = decls[k]->pos;
if (!x.file.size()) x.file = decls[k]->file;
try {
decls[k]->semant(e);
} catch (Ex& x) {
if (x.pos < 0)
x.pos = decls[k]->pos;
if (!x.file.size())
x.file = decls[k]->file;
throw;
}
}
}
void DeclSeqNode::translate(Codegen *g) {
void DeclSeqNode::translate(Codegen* g)
{
for (size_t k = 0; k < decls.size(); ++k) {
try { decls[k]->translate(g); } catch (Ex &x) {
if (x.pos < 0) x.pos = decls[k]->pos;
if (!x.file.size()) x.file = decls[k]->file;
try {
decls[k]->translate(g);
} catch (Ex& x) {
if (x.pos < 0)
x.pos = decls[k]->pos;
if (!x.file.size())
x.file = decls[k]->file;
throw;
}
}
}
void DeclSeqNode::transdata(Codegen *g) {
void DeclSeqNode::transdata(Codegen* g)
{
for (size_t k = 0; k < decls.size(); ++k) {
try { decls[k]->transdata(g); } catch (Ex &x) {
if (x.pos < 0) x.pos = decls[k]->pos;
if (!x.file.size()) x.file = decls[k]->file;
try {
decls[k]->transdata(g);
} catch (Ex& x) {
if (x.pos < 0)
x.pos = decls[k]->pos;
if (!x.file.size())
x.file = decls[k]->file;
throw;
}
}
@@ -48,10 +68,11 @@ void DeclSeqNode::transdata(Codegen *g) {
////////////////////////////
// Simple var declaration //
////////////////////////////
void VarDeclNode::proto(DeclSeq *d, Environ *e) {
void VarDeclNode::proto(DeclSeq* d, Environ* e)
{
Type* ty = tagType(tag, e);
if (!ty) ty = Type::int_type;
if (!ty)
ty = Type::int_type;
ConstType* defType = 0;
if (expr != nullptr) {
@@ -67,13 +88,17 @@ void VarDeclNode::proto(DeclSeq *d, Environ *e) {
if (constant || (kind & DECL_PARAM)) {
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());
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());
e->types.push_back(ty);
delete expr; expr = 0;
delete expr;
expr = 0;
}
if (expr == nullptr) {
@@ -81,55 +106,66 @@ void VarDeclNode::proto(DeclSeq *d, Environ *e) {
}
if (kind & DECL_PARAM) { // Heap corruption, this being replaced again?
defType = ty->constType(); ty = defType->valueType;
defType = ty->constType();
ty = defType->valueType;
}
} else if (constant) ex("Constants must be initialized");
} 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);
if (!decl)
ex("Duplicate variable name");
if (expr)
sem_var = new DeclVarNode(decl);
}
void VarDeclNode::semant(Environ* e) {}
void VarDeclNode::translate(Codegen *g) {
void VarDeclNode::translate(Codegen* g)
{
if (kind & DECL_GLOBAL) {
g->align_data(4);
g->i_data(0, "_v" + ident);
}
if (expr) g->code(sem_var->store(g, expr->translate(g)));
if (expr)
g->code(sem_var->store(g, expr->translate(g)));
}
//////////////////////////
// Function Declaration //
//////////////////////////
void FuncDeclNode::proto(DeclSeq *d, Environ *e) {
Type *t = tagType(tag, e); if (!t) t = Type::int_type;
void FuncDeclNode::proto(DeclSeq* d, Environ* e)
{
Type* t = tagType(tag, e);
if (!t)
t = Type::int_type;
a_ptr<DeclSeq> decls(new DeclSeq());
params->proto(decls, e);
sem_type = new FuncType(t, decls.release(), false, false);
if (!d->insertDecl(ident, sem_type, DECL_FUNC)) {
delete sem_type; ex("duplicate identifier");
delete sem_type;
ex("duplicate identifier");
}
e->types.push_back(sem_type);
}
void FuncDeclNode::semant(Environ *e) {
void FuncDeclNode::semant(Environ* e)
{
sem_env = new Environ(genLabel(), sem_type->returnType, 1, e);
DeclSeq* decls = sem_env->decls;
int k;
for (k = 0; k < sem_type->params->size(); ++k) {
Decl* d = sem_type->params->decls[k];
if (!decls->insertDecl(d->name, d->type, d->kind)) ex("duplicate identifier");
if (!decls->insertDecl(d->name, d->type, d->kind))
ex("duplicate identifier");
}
stmts->semant(sem_env);
}
void FuncDeclNode::translate(Codegen *g) {
void FuncDeclNode::translate(Codegen* g)
{
//var offsets
int size = enumVars(sem_env);
@@ -138,7 +174,8 @@ void FuncDeclNode::translate(Codegen *g) {
//initialize locals
TNode* t = createVars(sem_env);
if (t) g->code(t);
if (t)
g->code(t);
if (g->debug) {
string t = genLabel();
g->s_data(ident, t);
@@ -149,34 +186,40 @@ void FuncDeclNode::translate(Codegen *g) {
stmts->translate(g);
for (size_t k = 0; k < sem_env->labels.size(); ++k) {
if (sem_env->labels[k]->def < 0) ex("Undefined label", sem_env->labels[k]->ref);
if (sem_env->labels[k]->def < 0)
ex("Undefined label", sem_env->labels[k]->ref);
}
//leave the function
g->label(sem_env->funcLabel + "_leave");
t = deleteVars(sem_env);
if (g->debug) t = new TNode(IR_SEQ, call("__bbDebugLeave"), t);
if (g->debug)
t = new TNode(IR_SEQ, call("__bbDebugLeave"), t);
g->leave(t, sem_type->params->size() * 4);
}
//////////////////////
// Type Declaration //
//////////////////////
void StructDeclNode::proto(DeclSeq *d, Environ *e) {
void StructDeclNode::proto(DeclSeq* d, Environ* e)
{
sem_type = new StructType(ident, new DeclSeq());
if (!d->insertDecl(ident, sem_type, DECL_STRUCT)) {
delete sem_type; ex("Duplicate identifier");
delete sem_type;
ex("Duplicate identifier");
}
e->types.push_back(sem_type);
}
void StructDeclNode::semant(Environ *e) {
void StructDeclNode::semant(Environ* e)
{
fields->proto(sem_type->fields, e);
for (int k = 0; k < sem_type->fields->size(); ++k) sem_type->fields->decls[k]->offset = k * 4;
for (int k = 0; k < sem_type->fields->size(); ++k)
sem_type->fields->decls[k]->offset = k * 4;
}
void StructDeclNode::translate(Codegen *g) {
void StructDeclNode::translate(Codegen* g)
{
//translate fields
fields->translate(g);
@@ -203,86 +246,112 @@ void StructDeclNode::translate(Codegen *g) {
Decl* field = sem_type->fields->decls[k];
Type* type = field->type;
string t;
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;
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;
g->p_data(t);
}
}
//////////////////////
// Data declaration //
//////////////////////
void DataDeclNode::proto(DeclSeq *d, Environ *e) {
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();
if (!c)
ex("Data expression must be constant");
if (expr->sem_type == Type::string_type)
str_label = genLabel();
}
void DataDeclNode::semant(Environ* e) {}
void DataDeclNode::translate(Codegen *g) {
if (expr->sem_type != Type::string_type) return;
void DataDeclNode::translate(Codegen* g)
{
if (expr->sem_type != Type::string_type)
return;
ConstNode* c = expr->constNode();
g->s_data(c->stringValue(), str_label);
}
void DataDeclNode::transdata(Codegen *g) {
void DataDeclNode::transdata(Codegen* g)
{
ConstNode* c = expr->constNode();
if (expr->sem_type == Type::int_type) {
g->i_data(1); g->i_data(c->intValue());
g->i_data(1);
g->i_data(c->intValue());
} else if (expr->sem_type == Type::float_type) {
float n = c->floatValue();
g->i_data(2); g->i_data(*(int*)&n);
g->i_data(2);
g->i_data(*(int*)&n);
} else {
g->i_data(4); g->p_data(str_label);
g->i_data(4);
g->p_data(str_label);
}
}
////////////////////////
// Vector declaration //
////////////////////////
void VectorDeclNode::proto(DeclSeq *d, Environ *env) {
Type *ty = tagType(tag, env); if (!ty) ty = Type::int_type;
void VectorDeclNode::proto(DeclSeq* d, Environ* env)
{
Type* ty = tagType(tag, env);
if (!ty)
ty = Type::int_type;
vector<int> sizes;
for (int k = 0; k < exprs->size(); ++k) {
ExprNode* e = exprs->exprs[k] = exprs->exprs[k]->semant(env);
ConstNode* c = e->constNode();
if (!c) ex("Blitz array sizes must be constant");
if (!c)
ex("Blitz array sizes must be constant");
int n = c->intValue();
if (n < 0) ex("Blitz array sizes must not be negative");
if (n < 0)
ex("Blitz array sizes must not be negative");
sizes.push_back(n + 1);
}
string label = genLabel();
sem_type = new VectorType(label, ty, sizes);
if (!d->insertDecl(ident, sem_type, kind)) {
delete sem_type; ex("Duplicate identifier");
delete sem_type;
ex("Duplicate identifier");
}
env->types.push_back(sem_type);
}
void VectorDeclNode::translate(Codegen *g) {
void VectorDeclNode::translate(Codegen* g)
{
//type tag!
g->align_data(4);
VectorType* v = sem_type->vectorType();
g->i_data(6, v->label);
int sz = 1;
for (size_t k = 0; k < v->sizes.size(); ++k) sz *= v->sizes[k];
for (size_t k = 0; k < v->sizes.size(); ++k)
sz *= v->sizes[k];
g->i_data(sz);
string t;
Type* type = v->elementType;
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;
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;
g->p_data(t);
if (kind == DECL_GLOBAL) g->i_data(0, "_v" + ident);
if (kind == DECL_GLOBAL)
g->i_data(0, "_v" + ident);
}
+43 -11
View File
@@ -15,13 +15,23 @@ struct DeclNode : public Node{
struct DeclSeqNode : public Node {
vector<DeclNode*> decls;
DeclSeqNode() {}
~DeclSeqNode(){ for(;decls.size();decls.pop_back())delete decls.back(); }
~DeclSeqNode()
{
for (; decls.size(); decls.pop_back())
delete decls.back();
}
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
void transdata(Codegen* g);
void push_back( DeclNode *d ){ decls.push_back( d ); }
int size(){ return decls.size(); }
void push_back(DeclNode* d)
{
decls.push_back(d);
}
int size()
{
return decls.size();
}
};
#include "exprnode.hpp"
@@ -31,11 +41,18 @@ struct DeclSeqNode : public Node{
//should probably be LocalDeclNode,GlobalDeclNode,ParamDeclNode
struct VarDeclNode : public DeclNode {
string ident, tag;
int kind;bool constant;
int kind;
bool constant;
ExprNode* expr;
DeclVarNode* sem_var;
VarDeclNode( const string &i,const string &t,int k,bool c,ExprNode *e ):ident(i),tag(t),kind(k),constant(c),expr(e),sem_var(0){}
~VarDeclNode(){ delete expr;delete sem_var; }
VarDeclNode(const string& i, const string& t, int k, bool c, ExprNode* e)
: ident(i), tag(t), kind(k), constant(c), expr(e), sem_var(0)
{}
~VarDeclNode()
{
delete expr;
delete sem_var;
}
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
@@ -47,8 +64,14 @@ struct FuncDeclNode : public DeclNode{
StmtSeqNode* stmts;
FuncType* sem_type;
Environ* sem_env;
FuncDeclNode( const string &i,const string &t,DeclSeqNode *p,StmtSeqNode *ss ):ident(i),tag(t),params(p),stmts(ss){}
~FuncDeclNode(){ delete params;delete stmts; }
FuncDeclNode(const string& i, const string& t, DeclSeqNode* p, StmtSeqNode* ss)
: ident(i), tag(t), params(p), stmts(ss)
{}
~FuncDeclNode()
{
delete params;
delete stmts;
}
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
@@ -59,7 +82,10 @@ struct StructDeclNode : public DeclNode{
DeclSeqNode* fields;
StructType* sem_type;
StructDeclNode(const string& i, DeclSeqNode* f) : ident(i), fields(f) {}
~StructDeclNode(){ delete fields; }
~StructDeclNode()
{
delete fields;
}
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
@@ -69,7 +95,10 @@ struct DataDeclNode : public DeclNode{
ExprNode* expr;
string str_label;
DataDeclNode(ExprNode* e) : expr(e) {}
~DataDeclNode(){ delete expr; }
~DataDeclNode()
{
delete expr;
}
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
@@ -82,7 +111,10 @@ struct VectorDeclNode : public DeclNode{
int kind;
VectorType* sem_type;
VectorDeclNode(const string& i, const string& t, ExprSeqNode* e, int k) : ident(i), tag(t), exprs(e), kind(k) {}
~VectorDeclNode(){ delete exprs; }
~VectorDeclNode()
{
delete exprs;
}
void proto(DeclSeq* d, Environ* e);
void translate(Codegen* g);
};
+48 -25
View File
@@ -1,67 +1,90 @@
#include "std.hpp"
#include "environ.hpp"
#include "std.hpp"
Environ::Environ( const string &f,Type *r,int l,Environ *gs )
:funcLabel(f),returnType(r),level(l),globals(gs){
Environ::Environ(const string& f, Type* r, int l, Environ* gs) : funcLabel(f), returnType(r), level(l), globals(gs)
{
decls = new DeclSeq();
typeDecls = new DeclSeq();
funcDecls = new DeclSeq();
if( globals ) globals->children.push_back( this );
if (globals)
globals->children.push_back(this);
}
Environ::~Environ(){
if( globals ) globals->children.remove( this );
while( children.size() ) delete children.back();
for( ;labels.size();labels.pop_back() ) delete labels.back();
Environ::~Environ()
{
if (globals)
globals->children.remove(this);
while (children.size())
delete children.back();
for (; labels.size(); labels.pop_back())
delete labels.back();
//delete all types
delete decls;
delete funcDecls;
delete typeDecls;
for( int k=0;k<types.size();++k ) delete types[k];
for (int k = 0; k < types.size(); ++k)
delete types[k];
}
Decl *Environ::findDecl( const string &s ){
Decl* Environ::findDecl(const string& s)
{
for (Environ* e = this; e; e = e->globals) {
if (Decl* d = e->decls->findDecl(s)) {
if (d->kind & (DECL_LOCAL | DECL_PARAM)) {
if( e==this ) return d;
}else return d;
if (e == this)
return d;
} else
return d;
}
}
return 0;
}
Decl *Environ::findFunc( const string &s ){
Decl* Environ::findFunc(const string& s)
{
for (Environ* e = this; e; e = e->globals) {
if( Decl *d=e->funcDecls->findDecl( s ) ) return d;
if (Decl* d = e->funcDecls->findDecl(s))
return d;
}
return 0;
}
Type *Environ::findType( const string &s ){
if( s=="%" ) return Type::int_type;
if( s=="#" ) return Type::float_type;
if( s=="$" ) return Type::string_type;
Type* Environ::findType(const string& s)
{
if (s == "%")
return Type::int_type;
if (s == "#")
return Type::float_type;
if (s == "$")
return Type::string_type;
for (Environ* e = this; e; e = e->globals) {
if( Decl *d=e->typeDecls->findDecl( s ) ) return d->type->structType();
if (Decl* d = e->typeDecls->findDecl(s))
return d->type->structType();
}
return 0;
}
Label *Environ::findLabel( const string &s ){
for( int k=0;k<labels.size();++k ) if( labels[k]->name==s ) return labels[k];
Label* Environ::findLabel(const string& s)
{
for (int k = 0; k < labels.size(); ++k)
if (labels[k]->name == s)
return labels[k];
return 0;
}
Label *Environ::insertLabel( const string &s,int def,int src,int sz ){
Label* Environ::insertLabel(const string& s, int def, int src, int sz)
{
Label* l = new Label(s, def, src, sz);
labels.push_back( l );return l;
labels.push_back(l);
return l;
}
string Environ::setBreak( const string &s ){
string Environ::setBreak(const string& s)
{
string t = breakLabel;
breakLabel=s;return t;
breakLabel = s;
return t;
}
+1 -1
View File
@@ -8,9 +8,9 @@
#ifndef ENVIRON_H
#define ENVIRON_H
#include "type.hpp"
#include "decl.hpp"
#include "label.hpp"
#include "type.hpp"
class Environ {
public:
+364 -148
View File
@@ -1,14 +1,15 @@
#include "std.hpp"
#include "nodes.hpp"
#include "std.hpp"
#include <math.h>
#include <float.h>
#include <math.h>
//////////////////////////////////
// Cast an expression to a type //
//////////////////////////////////
ExprNode *ExprNode::castTo(Type *ty, Environ *e) {
ExprNode* ExprNode::castTo(Type* ty, Environ* e)
{
if (!sem_type->canCastTo(ty)) {
ex("Illegal type conversion");
}
@@ -18,16 +19,20 @@ ExprNode *ExprNode::castTo(Type *ty, Environ *e) {
return cast;
}
ExprNode *CastNode::semant(Environ *e) {
ExprNode* CastNode::semant(Environ* e)
{
if (!expr->sem_type) {
expr = expr->semant(e);
}
if (ConstNode* c = expr->constNode()) {
ExprNode* e;
if (type == Type::int_type) e = new IntConstNode(c->intValue());
else if (type == Type::float_type) e = new FloatConstNode(c->floatValue());
else e = new StringConstNode(c->stringValue());
if (type == Type::int_type)
e = new IntConstNode(c->intValue());
else if (type == Type::float_type)
e = new FloatConstNode(c->floatValue());
else
e = new StringConstNode(c->stringValue());
delete this;
return e;
}
@@ -39,7 +44,8 @@ ExprNode *CastNode::semant(Environ *e) {
//////////////////////////////////
// Cast an expression to a type //
//////////////////////////////////
TNode *CastNode::translate(Codegen *g) {
TNode* CastNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
if (expr->sem_type == Type::float_type && sem_type == Type::int_type) {
//float->int
@@ -75,16 +81,18 @@ TNode *CastNode::translate(Codegen *g) {
/////////////////////////////
// Sequence of Expressions //
/////////////////////////////
void ExprSeqNode::semant(Environ *e) {
void ExprSeqNode::semant(Environ* e)
{
for (int k = 0; k < exprs.size(); ++k) {
if (exprs[k]) exprs[k] = exprs[k]->semant(e);
if (exprs[k])
exprs[k] = exprs[k]->semant(e);
}
}
TNode *ExprSeqNode::translate(Codegen *g, bool cfunc) {
TNode* ExprSeqNode::translate(Codegen* g, bool cfunc)
{
TNode *t = 0, *l = 0;
for (int k = 0; k < exprs.size(); ++k) {
TNode* q = exprs[k]->translate(g);
if (cfunc) {
@@ -103,19 +111,22 @@ TNode *ExprSeqNode::translate(Codegen *g, bool cfunc) {
p = new TNode(IR_MEM, p, 0);
p = new TNode(IR_MOVE, q, p);
p = new TNode(IR_SEQ, p, 0);
if (l) l->r = p;
else t = p;
if (l)
l->r = p;
else
t = p;
l = p;
}
return t;
}
void ExprSeqNode::castTo(DeclSeq *decls, Environ *e, bool cfunc) {
if (exprs.size() > decls->size()) ex("Too many parameters");
void ExprSeqNode::castTo(DeclSeq* decls, Environ* e, bool cfunc)
{
if (exprs.size() > decls->size())
ex("Too many parameters");
for (int k = 0; k < decls->size(); ++k) {
Decl* d = decls->decls[k];
if (k < exprs.size() && exprs[k]) {
if (cfunc && d->type->structType()) {
if (exprs[k]->sem_type->structType()) {
} else if (exprs[k]->sem_type->intType()) {
@@ -129,15 +140,19 @@ void ExprSeqNode::castTo(DeclSeq *decls, Environ *e, bool cfunc) {
exprs[k] = exprs[k]->castTo(d->type, e);
} else {
if (!d->defType) ex("Not enough parameters");
if (!d->defType)
ex("Not enough parameters");
ExprNode* expr = constValue(d->defType);
if (k < exprs.size()) exprs[k] = expr;
else exprs.push_back(expr);
if (k < exprs.size())
exprs[k] = expr;
else
exprs.push_back(expr);
}
}
}
void ExprSeqNode::castTo(Type *t, Environ *e) {
void ExprSeqNode::castTo(Type* t, Environ* e)
{
for (int k = 0; k < exprs.size(); ++k) {
exprs[k] = exprs[k]->castTo(t, e);
}
@@ -146,20 +161,23 @@ void ExprSeqNode::castTo(Type *t, Environ *e) {
///////////////////
// Function call //
///////////////////
ExprNode *CallNode::semant(Environ *e) {
ExprNode* CallNode::semant(Environ* e)
{
Type* t = e->findType(tag);
sem_decl = e->findFunc(ident);
if (!sem_decl || !(sem_decl->kind & DECL_FUNC)) ex("Function '" + ident + "' not found");
if (!sem_decl || !(sem_decl->kind & DECL_FUNC))
ex("Function '" + ident + "' not found");
FuncType* f = sem_decl->type->funcType();
if (t && f->returnType != t) ex("incorrect function return type");
if (t && f->returnType != t)
ex("incorrect function return type");
exprs->semant(e);
exprs->castTo(f->params, e, f->cfunc);
sem_type = f->returnType;
return this;
}
TNode *CallNode::translate(Codegen *g) {
TNode* CallNode::translate(Codegen* g)
{
FuncType* f = sem_decl->type->funcType();
TNode* t;
@@ -188,57 +206,71 @@ TNode *CallNode::translate(Codegen *g) {
/////////////////////////
// Variable expression //
/////////////////////////
ExprNode *VarExprNode::semant(Environ *e) {
ExprNode* VarExprNode::semant(Environ* e)
{
var->semant(e);
sem_type = var->sem_type;
ConstType* c = sem_type->constType();
if (!c) return this;
if (!c)
return this;
ExprNode* expr = constValue(c);
delete this; return expr;
delete this;
return expr;
}
TNode *VarExprNode::translate(Codegen *g) {
TNode* VarExprNode::translate(Codegen* g)
{
return var->load(g);
}
//////////////////////
// Integer constant //
//////////////////////
IntConstNode::IntConstNode(int n) :value(n) {
IntConstNode::IntConstNode(int n) : value(n)
{
sem_type = Type::int_type;
}
TNode *IntConstNode::translate(Codegen *g) {
TNode* IntConstNode::translate(Codegen* g)
{
return new TNode(IR_CONST, 0, 0, value);
}
int IntConstNode::intValue() {
int IntConstNode::intValue()
{
return value;
}
float IntConstNode::floatValue() {
float IntConstNode::floatValue()
{
return value;
}
string IntConstNode::stringValue() {
string IntConstNode::stringValue()
{
return itoa(value);
}
////////////////////
// Float constant //
////////////////////
FloatConstNode::FloatConstNode(float f) :value(f) {
FloatConstNode::FloatConstNode(float f) : value(f)
{
sem_type = Type::float_type;
}
TNode *FloatConstNode::translate(Codegen *g) {
TNode* FloatConstNode::translate(Codegen* g)
{
return new TNode(IR_CONST, 0, 0, *(int*)&value);
}
int FloatConstNode::intValue() {
int FloatConstNode::intValue()
{
float flt = value;
int temp;
_control87(_RC_NEAR | _PC_24 | _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT | _EM_DENORMAL, 0xfffff);
_control87(_RC_NEAR | _PC_24 | _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT
| _EM_DENORMAL,
0xfffff);
_asm {
fld[flt];
fistp[temp];
@@ -247,61 +279,86 @@ int FloatConstNode::intValue() {
return temp;
}
float FloatConstNode::floatValue() {
float FloatConstNode::floatValue()
{
return value;
}
string FloatConstNode::stringValue() {
string FloatConstNode::stringValue()
{
return ftoa(value);
}
/////////////////////
// String constant //
/////////////////////
StringConstNode::StringConstNode(const string &s) :value(s) {
StringConstNode::StringConstNode(const string& s) : value(s)
{
sem_type = Type::string_type;
}
TNode *StringConstNode::translate(Codegen *g) {
TNode* StringConstNode::translate(Codegen* g)
{
string lab = genLabel();
g->s_data(value, lab);
return call("__bbStrConst", global(lab));
}
int StringConstNode::intValue() {
int StringConstNode::intValue()
{
return atoi(value);
}
float StringConstNode::floatValue() {
float StringConstNode::floatValue()
{
return (float)atof(value);
}
string StringConstNode::stringValue() {
string StringConstNode::stringValue()
{
return value;
}
////////////////////
// Unary operator //
////////////////////
ExprNode *UniExprNode::semant(Environ *e) {
ExprNode* UniExprNode::semant(Environ* e)
{
expr = expr->semant(e);
sem_type = expr->sem_type;
if (sem_type != Type::int_type && sem_type != Type::float_type) ex("Illegal operator for type");
if (sem_type != Type::int_type && sem_type != Type::float_type)
ex("Illegal operator for type");
if (ConstNode* c = expr->constNode()) {
ExprNode* e;
if (sem_type == Type::int_type) {
switch (op) {
case '+':e = new IntConstNode(+c->intValue()); break;
case '-':e = new IntConstNode(-c->intValue()); break;
case ABS:e = new IntConstNode(c->intValue() >= 0 ? c->intValue() : -c->intValue()); break;
case SGN:e = new IntConstNode(c->intValue() > 0 ? 1 : (c->intValue() < 0 ? -1 : 0)); break;
case '+':
e = new IntConstNode(+c->intValue());
break;
case '-':
e = new IntConstNode(-c->intValue());
break;
case ABS:
e = new IntConstNode(c->intValue() >= 0 ? c->intValue() : -c->intValue());
break;
case SGN:
e = new IntConstNode(c->intValue() > 0 ? 1 : (c->intValue() < 0 ? -1 : 0));
break;
}
} else {
switch (op) {
case '+':e = new FloatConstNode(+c->floatValue()); break;
case '-':e = new FloatConstNode(-c->floatValue()); break;
case ABS:e = new FloatConstNode(c->floatValue() >= 0 ? c->floatValue() : -c->floatValue()); break;
case SGN:e = new FloatConstNode(c->floatValue() > 0 ? 1 : (c->floatValue() < 0 ? -1 : 0)); break;
case '+':
e = new FloatConstNode(+c->floatValue());
break;
case '-':
e = new FloatConstNode(-c->floatValue());
break;
case ABS:
e = new FloatConstNode(c->floatValue() >= 0 ? c->floatValue() : -c->floatValue());
break;
case SGN:
e = new FloatConstNode(c->floatValue() > 0 ? 1 : (c->floatValue() < 0 ? -1 : 0));
break;
}
}
delete this;
@@ -310,22 +367,33 @@ ExprNode *UniExprNode::semant(Environ *e) {
return this;
}
TNode *UniExprNode::translate(Codegen *g) {
TNode* UniExprNode::translate(Codegen* g)
{
int n = 0;
TNode* l = expr->translate(g);
if (sem_type == Type::int_type) {
switch (op) {
case '+':return l;
case '-':n = IR_NEG; break;
case ABS:return call("__bbAbs", l);
case SGN:return call("__bbSgn", l);
case '+':
return l;
case '-':
n = IR_NEG;
break;
case ABS:
return call("__bbAbs", l);
case SGN:
return call("__bbSgn", l);
}
} else {
switch (op) {
case '+':return l;
case '-':n = IR_FNEG; break;
case ABS:return fcall("__bbFAbs", l);
case SGN:return fcall("__bbFSgn", l);
case '+':
return l;
case '-':
n = IR_FNEG;
break;
case ABS:
return fcall("__bbFAbs", l);
case SGN:
return fcall("__bbFSgn", l);
}
}
return new TNode(n, l, 0);
@@ -334,19 +402,34 @@ TNode *UniExprNode::translate(Codegen *g) {
/////////////////////////////////////////////////////
// boolean expression - accepts ints, returns ints //
/////////////////////////////////////////////////////
ExprNode *BinExprNode::semant(Environ *e) {
lhs = lhs->semant(e); lhs = lhs->castTo(Type::int_type, e);
rhs = rhs->semant(e); rhs = rhs->castTo(Type::int_type, e);
ExprNode* BinExprNode::semant(Environ* e)
{
lhs = lhs->semant(e);
lhs = lhs->castTo(Type::int_type, e);
rhs = rhs->semant(e);
rhs = rhs->castTo(Type::int_type, e);
ConstNode *lc = lhs->constNode(), *rc = rhs->constNode();
if (lc && rc) {
ExprNode* expr = nullptr;
switch (op) {
case AND:expr = new IntConstNode(lc->intValue() & rc->intValue()); break;
case OR: expr = new IntConstNode(lc->intValue() | rc->intValue()); break;
case XOR:expr = new IntConstNode(lc->intValue() ^ rc->intValue()); break;
case SHL:expr = new IntConstNode(lc->intValue() << rc->intValue()); break;
case SHR:expr = new IntConstNode((unsigned)lc->intValue() >> rc->intValue()); break;
case SAR:expr = new IntConstNode(lc->intValue() >> rc->intValue()); break;
case AND:
expr = new IntConstNode(lc->intValue() & rc->intValue());
break;
case OR:
expr = new IntConstNode(lc->intValue() | rc->intValue());
break;
case XOR:
expr = new IntConstNode(lc->intValue() ^ rc->intValue());
break;
case SHL:
expr = new IntConstNode(lc->intValue() << rc->intValue());
break;
case SHR:
expr = new IntConstNode((unsigned)lc->intValue() >> rc->intValue());
break;
case SAR:
expr = new IntConstNode(lc->intValue() >> rc->intValue());
break;
}
delete this;
return expr;
@@ -355,13 +438,30 @@ ExprNode *BinExprNode::semant(Environ *e) {
return this;
}
TNode *BinExprNode::translate(Codegen *g) {
TNode* BinExprNode::translate(Codegen* g)
{
TNode* l = lhs->translate(g);
TNode* r = rhs->translate(g);
int n = 0;
switch (op) {
case AND:n = IR_AND; break; case OR:n = IR_OR; break; case XOR:n = IR_XOR; break;
case SHL:n = IR_SHL; break; case SHR:n = IR_SHR; break; case SAR:n = IR_SAR; break;
case AND:
n = IR_AND;
break;
case OR:
n = IR_OR;
break;
case XOR:
n = IR_XOR;
break;
case SHL:
n = IR_SHL;
break;
case SHR:
n = IR_SHR;
break;
case SAR:
n = IR_SAR;
break;
}
return new TNode(n, l, r);
}
@@ -369,7 +469,8 @@ TNode *BinExprNode::translate(Codegen *g) {
///////////////////////////
// arithmetic expression //
///////////////////////////
ExprNode *ArithExprNode::semant(Environ *e) {
ExprNode* ArithExprNode::semant(Environ* e)
{
lhs = lhs->semant(e);
rhs = rhs->semant(e);
if (lhs->sem_type->structType() || rhs->sem_type->structType()) {
@@ -377,7 +478,8 @@ ExprNode *ArithExprNode::semant(Environ *e) {
}
if (lhs->sem_type == Type::string_type || rhs->sem_type == Type::string_type) {
//one side is a string - only + operator...
if (op != '+') ex("Operator cannot be applied to strings");
if (op != '+')
ex("Operator cannot be applied to strings");
sem_type = Type::string_type;
} else if (op == '^' || lhs->sem_type == Type::float_type || rhs->sem_type == Type::float_type) {
//It's ^, or one side is a float
@@ -400,20 +502,42 @@ ExprNode *ArithExprNode::semant(Environ *e) {
expr = new StringConstNode(lc->stringValue() + rc->stringValue());
} else if (sem_type == Type::int_type) {
switch (op) {
case '+':expr = new IntConstNode(lc->intValue() + rc->intValue()); break;
case '-':expr = new IntConstNode(lc->intValue() - rc->intValue()); break;
case '*':expr = new IntConstNode(lc->intValue()*rc->intValue()); break;
case '/':expr = new IntConstNode(lc->intValue() / rc->intValue()); break;
case MOD:expr = new IntConstNode(lc->intValue() % rc->intValue()); break;
case '+':
expr = new IntConstNode(lc->intValue() + rc->intValue());
break;
case '-':
expr = new IntConstNode(lc->intValue() - rc->intValue());
break;
case '*':
expr = new IntConstNode(lc->intValue() * rc->intValue());
break;
case '/':
expr = new IntConstNode(lc->intValue() / rc->intValue());
break;
case MOD:
expr = new IntConstNode(lc->intValue() % rc->intValue());
break;
}
} else {
switch (op) {
case '+':expr = new FloatConstNode(lc->floatValue() + rc->floatValue()); break;
case '-':expr = new FloatConstNode(lc->floatValue() - rc->floatValue()); break;
case '*':expr = new FloatConstNode(lc->floatValue()*rc->floatValue()); break;
case '/':expr = new FloatConstNode(lc->floatValue() / rc->floatValue()); break;
case MOD:expr = new FloatConstNode(fmod(lc->floatValue(), rc->floatValue())); break;
case '^':expr = new FloatConstNode(pow(lc->floatValue(), rc->floatValue())); break;
case '+':
expr = new FloatConstNode(lc->floatValue() + rc->floatValue());
break;
case '-':
expr = new FloatConstNode(lc->floatValue() - rc->floatValue());
break;
case '*':
expr = new FloatConstNode(lc->floatValue() * rc->floatValue());
break;
case '/':
expr = new FloatConstNode(lc->floatValue() / rc->floatValue());
break;
case MOD:
expr = new FloatConstNode(fmod(lc->floatValue(), rc->floatValue()));
break;
case '^':
expr = new FloatConstNode(pow(lc->floatValue(), rc->floatValue()));
break;
}
}
delete this;
@@ -422,7 +546,8 @@ ExprNode *ArithExprNode::semant(Environ *e) {
return this;
}
TNode *ArithExprNode::translate(Codegen *g) {
TNode* ArithExprNode::translate(Codegen* g)
{
TNode* l = lhs->translate(g);
TNode* r = rhs->translate(g);
if (sem_type == Type::string_type) {
@@ -431,16 +556,39 @@ TNode *ArithExprNode::translate(Codegen *g) {
int n = 0;
if (sem_type == Type::int_type) {
switch (op) {
case '+':n = IR_ADD; break; case '-':n = IR_SUB; break;
case '*':n = IR_MUL; break; case '/':n = IR_DIV; break;
case MOD:return call("__bbMod", l, r);
case '+':
n = IR_ADD;
break;
case '-':
n = IR_SUB;
break;
case '*':
n = IR_MUL;
break;
case '/':
n = IR_DIV;
break;
case MOD:
return call("__bbMod", l, r);
}
} else {
switch (op) {
case '+':n = IR_FADD; break; case '-':n = IR_FSUB; break;
case '*':n = IR_FMUL; break; case '/':n = IR_FDIV; break;
case MOD:return fcall("__bbFMod", l, r);
case '^':return fcall("__bbFPow", l, r);
case '+':
n = IR_FADD;
break;
case '-':
n = IR_FSUB;
break;
case '*':
n = IR_FMUL;
break;
case '/':
n = IR_FDIV;
break;
case MOD:
return fcall("__bbFMod", l, r);
case '^':
return fcall("__bbFPow", l, r);
}
}
return new TNode(n, l, r);
@@ -449,11 +597,13 @@ TNode *ArithExprNode::translate(Codegen *g) {
/////////////////////////
// relation expression //
/////////////////////////
ExprNode *RelExprNode::semant(Environ *e) {
ExprNode* RelExprNode::semant(Environ* e)
{
lhs = lhs->semant(e);
rhs = rhs->semant(e);
if (lhs->sem_type->structType() || rhs->sem_type->structType()) {
if (op != '=' && op != NE) ex("Illegal operator for custom type objects");
if (op != '=' && op != NE)
ex("Illegal operator for custom type objects");
opType = lhs->sem_type != Type::null_type ? lhs->sem_type : rhs->sem_type;
} else if (lhs->sem_type == Type::string_type || rhs->sem_type == Type::string_type) {
opType = Type::string_type;
@@ -470,30 +620,66 @@ ExprNode *RelExprNode::semant(Environ *e) {
ExprNode* expr = nullptr;
if (opType == Type::string_type) {
switch (op) {
case '<':expr = new IntConstNode(lc->stringValue() < rc->stringValue()); break;
case '=':expr = new IntConstNode(lc->stringValue() == rc->stringValue()); break;
case '>':expr = new IntConstNode(lc->stringValue() > rc->stringValue()); break;
case LE: expr = new IntConstNode(lc->stringValue() <= rc->stringValue()); break;
case NE: expr = new IntConstNode(lc->stringValue() != rc->stringValue()); break;
case GE: expr = new IntConstNode(lc->stringValue() >= rc->stringValue()); break;
case '<':
expr = new IntConstNode(lc->stringValue() < rc->stringValue());
break;
case '=':
expr = new IntConstNode(lc->stringValue() == rc->stringValue());
break;
case '>':
expr = new IntConstNode(lc->stringValue() > rc->stringValue());
break;
case LE:
expr = new IntConstNode(lc->stringValue() <= rc->stringValue());
break;
case NE:
expr = new IntConstNode(lc->stringValue() != rc->stringValue());
break;
case GE:
expr = new IntConstNode(lc->stringValue() >= rc->stringValue());
break;
}
} else if (opType == Type::float_type) {
switch (op) {
case '<':expr = new IntConstNode(lc->floatValue() < rc->floatValue()); break;
case '=':expr = new IntConstNode(lc->floatValue() == rc->floatValue()); break;
case '>':expr = new IntConstNode(lc->floatValue() > rc->floatValue()); break;
case LE: expr = new IntConstNode(lc->floatValue() <= rc->floatValue()); break;
case NE: expr = new IntConstNode(lc->floatValue() != rc->floatValue()); break;
case GE: expr = new IntConstNode(lc->floatValue() >= rc->floatValue()); break;
case '<':
expr = new IntConstNode(lc->floatValue() < rc->floatValue());
break;
case '=':
expr = new IntConstNode(lc->floatValue() == rc->floatValue());
break;
case '>':
expr = new IntConstNode(lc->floatValue() > rc->floatValue());
break;
case LE:
expr = new IntConstNode(lc->floatValue() <= rc->floatValue());
break;
case NE:
expr = new IntConstNode(lc->floatValue() != rc->floatValue());
break;
case GE:
expr = new IntConstNode(lc->floatValue() >= rc->floatValue());
break;
}
} else {
switch (op) {
case '<':expr = new IntConstNode(lc->intValue() < rc->intValue()); break;
case '=':expr = new IntConstNode(lc->intValue() == rc->intValue()); break;
case '>':expr = new IntConstNode(lc->intValue() > rc->intValue()); break;
case LE: expr = new IntConstNode(lc->intValue() <= rc->intValue()); break;
case NE: expr = new IntConstNode(lc->intValue() != rc->intValue()); break;
case GE: expr = new IntConstNode(lc->intValue() >= rc->intValue()); break;
case '<':
expr = new IntConstNode(lc->intValue() < rc->intValue());
break;
case '=':
expr = new IntConstNode(lc->intValue() == rc->intValue());
break;
case '>':
expr = new IntConstNode(lc->intValue() > rc->intValue());
break;
case LE:
expr = new IntConstNode(lc->intValue() <= rc->intValue());
break;
case NE:
expr = new IntConstNode(lc->intValue() != rc->intValue());
break;
case GE:
expr = new IntConstNode(lc->intValue() >= rc->intValue());
break;
}
}
delete this;
@@ -502,7 +688,8 @@ ExprNode *RelExprNode::semant(Environ *e) {
return this;
}
TNode *RelExprNode::translate(Codegen *g) {
TNode* RelExprNode::translate(Codegen* g)
{
TNode* l = lhs->translate(g);
TNode* r = rhs->translate(g);
return compare(op, l, r, opType);
@@ -511,102 +698,128 @@ TNode *RelExprNode::translate(Codegen *g) {
////////////////////
// New expression //
////////////////////
ExprNode *NewNode::semant(Environ *e) {
ExprNode* NewNode::semant(Environ* e)
{
sem_type = e->findType(ident);
if (!sem_type) ex("custom type name not found");
if (sem_type->structType() == 0) ex("type is not a custom type");
if (!sem_type)
ex("custom type name not found");
if (sem_type->structType() == 0)
ex("type is not a custom type");
return this;
}
TNode *NewNode::translate(Codegen *g) {
TNode* NewNode::translate(Codegen* g)
{
return call("__bbObjNew", global("_t" + ident));
}
////////////////////
// First of class //
////////////////////
ExprNode *FirstNode::semant(Environ *e) {
ExprNode* FirstNode::semant(Environ* e)
{
sem_type = e->findType(ident);
if (!sem_type) ex("custom type name name not found");
if (!sem_type)
ex("custom type name name not found");
return this;
}
TNode *FirstNode::translate(Codegen *g) {
TNode* FirstNode::translate(Codegen* g)
{
return call("__bbObjFirst", global("_t" + ident));
}
///////////////////
// Last of class //
///////////////////
ExprNode *LastNode::semant(Environ *e) {
ExprNode* LastNode::semant(Environ* e)
{
sem_type = e->findType(ident);
if (!sem_type) ex("custom type name not found");
if (!sem_type)
ex("custom type name not found");
return this;
}
TNode *LastNode::translate(Codegen *g) {
TNode* LastNode::translate(Codegen* g)
{
return call("__bbObjLast", global("_t" + ident));
}
////////////////////
// Next of object //
////////////////////
ExprNode *AfterNode::semant(Environ *e) {
ExprNode* AfterNode::semant(Environ* e)
{
expr = expr->semant(e);
if (expr->sem_type == Type::null_type) ex("'After' cannot be used on 'Null'");
if (expr->sem_type->structType() == 0) ex("'After' must be used with a custom type object");
if (expr->sem_type == Type::null_type)
ex("'After' cannot be used on 'Null'");
if (expr->sem_type->structType() == 0)
ex("'After' must be used with a custom type object");
sem_type = expr->sem_type;
return this;
}
TNode *AfterNode::translate(Codegen *g) {
TNode* AfterNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
if (g->debug) t = jumpf(t, "__bbNullObjEx");
if (g->debug)
t = jumpf(t, "__bbNullObjEx");
return call("__bbObjNext", t);
}
////////////////////
// Prev of object //
////////////////////
ExprNode *BeforeNode::semant(Environ *e) {
ExprNode* BeforeNode::semant(Environ* e)
{
expr = expr->semant(e);
if (expr->sem_type == Type::null_type) ex("'Before' cannot be used with 'Null'");
if (expr->sem_type->structType() == 0) ex("'Before' must be used with a custom type object");
if (expr->sem_type == Type::null_type)
ex("'Before' cannot be used with 'Null'");
if (expr->sem_type->structType() == 0)
ex("'Before' must be used with a custom type object");
sem_type = expr->sem_type;
return this;
}
TNode *BeforeNode::translate(Codegen *g) {
TNode* BeforeNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
if (g->debug) t = jumpf(t, "__bbNullObjEx");
if (g->debug)
t = jumpf(t, "__bbNullObjEx");
return call("__bbObjPrev", t);
}
/////////////////
// Null object //
/////////////////
ExprNode *NullNode::semant(Environ *e) {
ExprNode* NullNode::semant(Environ* e)
{
sem_type = Type::null_type;
return this;
}
TNode *NullNode::translate(Codegen *g) {
TNode* NullNode::translate(Codegen* g)
{
return new TNode(IR_CONST, 0, 0, 0);
}
/////////////////
// Object cast //
/////////////////
ExprNode *ObjectCastNode::semant(Environ *e) {
ExprNode* ObjectCastNode::semant(Environ* e)
{
expr = expr->semant(e);
expr = expr->castTo(Type::int_type, e);
sem_type = e->findType(type_ident);
if (!sem_type) ex("custom type name not found");
if (!sem_type->structType()) ex("type is not a custom type");
if (!sem_type)
ex("custom type name not found");
if (!sem_type->structType())
ex("type is not a custom type");
return this;
}
TNode *ObjectCastNode::translate(Codegen *g) {
TNode* ObjectCastNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
t = call("__bbObjFromHandle", t, global("_t" + sem_type->structType()->ident));
return t;
@@ -615,14 +828,17 @@ TNode *ObjectCastNode::translate(Codegen *g) {
///////////////////
// Object Handle //
///////////////////
ExprNode *ObjectHandleNode::semant(Environ *e) {
ExprNode* ObjectHandleNode::semant(Environ* e)
{
expr = expr->semant(e);
if (!expr->sem_type->structType()) ex("'ObjectHandle' must be used with an object");
if (!expr->sem_type->structType())
ex("'ObjectHandle' must be used with an object");
sem_type = Type::int_type;
return this;
}
TNode *ObjectHandleNode::translate(Codegen *g) {
TNode* ObjectHandleNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
return call("__bbObjToHandle", t);
}
+80 -21
View File
@@ -16,14 +16,27 @@ struct ExprNode : public Node {
virtual ExprNode* semant(Environ* e) = 0;
virtual TNode* translate(Codegen* g) = 0;
virtual ConstNode *constNode() { return 0; }
virtual ConstNode* constNode()
{
return 0;
}
};
struct ExprSeqNode : public Node {
vector<ExprNode*> exprs;
~ExprSeqNode() { for (; exprs.size(); exprs.pop_back()) delete exprs.back(); }
void push_back(ExprNode *e) { exprs.push_back(e); }
int size() { return exprs.size(); }
~ExprSeqNode()
{
for (; exprs.size(); exprs.pop_back())
delete exprs.back();
}
void push_back(ExprNode* e)
{
exprs.push_back(e);
}
int size()
{
return exprs.size();
}
void semant(Environ* e);
TNode* translate(Codegen* g, bool userlib);
void castTo(DeclSeq* ds, Environ* e, bool userlib);
@@ -36,7 +49,10 @@ struct CastNode : public ExprNode {
ExprNode* expr;
Type* type;
CastNode(ExprNode* ex, Type* ty) : expr(ex), type(ty) {}
~CastNode() { delete expr; }
~CastNode()
{
delete expr;
}
ExprNode* semant(Environ* e);
TNode* translate(Codegen* g);
};
@@ -46,7 +62,10 @@ struct CallNode : public ExprNode {
ExprSeqNode* exprs;
Decl* sem_decl;
CallNode(const string& i, const string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {}
~CallNode() { delete exprs; }
~CallNode()
{
delete exprs;
}
ExprNode* semant(Environ* e);
TNode* translate(Codegen* g);
};
@@ -54,14 +73,23 @@ struct CallNode : public ExprNode {
struct VarExprNode : public ExprNode {
VarNode* var;
VarExprNode(VarNode* v) : var(v) {}
~VarExprNode() { delete var; }
~VarExprNode()
{
delete var;
}
ExprNode* semant(Environ* e);
TNode* translate(Codegen* g);
};
struct ConstNode : public ExprNode {
ExprNode *semant(Environ *e) { return this; }
ConstNode *constNode() { return this; }
ExprNode* semant(Environ* e)
{
return this;
}
ConstNode* constNode()
{
return this;
}
virtual int intValue() = 0;
virtual float floatValue() = 0;
virtual string stringValue() = 0;
@@ -95,9 +123,13 @@ struct StringConstNode : public ConstNode {
};
struct UniExprNode : public ExprNode {
int op; ExprNode *expr;
int op;
ExprNode* expr;
UniExprNode(int op, ExprNode* expr) : op(op), expr(expr) {}
~UniExprNode() { delete expr; }
~UniExprNode()
{
delete expr;
}
ExprNode* constize();
ExprNode* semant(Environ* e);
TNode* translate(Codegen* g);
@@ -105,28 +137,43 @@ struct UniExprNode : public ExprNode {
// and, or, eor, lsl, lsr, asr
struct BinExprNode : public ExprNode {
int op; ExprNode *lhs, *rhs;
int op;
ExprNode *lhs, *rhs;
BinExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {}
~BinExprNode() { delete lhs; delete rhs; }
~BinExprNode()
{
delete lhs;
delete rhs;
}
ExprNode* semant(Environ* e);
TNode* translate(Codegen* g);
};
// *,/,Mod,+,-
struct ArithExprNode : public ExprNode {
int op; ExprNode *lhs, *rhs;
int op;
ExprNode *lhs, *rhs;
ArithExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {}
~ArithExprNode() { delete lhs; delete rhs; }
~ArithExprNode()
{
delete lhs;
delete rhs;
}
ExprNode* semant(Environ* e);
TNode* translate(Codegen* g);
};
//<,=,>,<=,<>,>=
struct RelExprNode : public ExprNode {
int op; ExprNode *lhs, *rhs;
int op;
ExprNode *lhs, *rhs;
Type* opType;
RelExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {}
~RelExprNode() { delete lhs; delete rhs; }
~RelExprNode()
{
delete lhs;
delete rhs;
}
ExprNode* semant(Environ* e);
TNode* translate(Codegen* g);
};
@@ -155,7 +202,10 @@ struct LastNode : public ExprNode {
struct AfterNode : public ExprNode {
ExprNode* expr;
AfterNode(ExprNode* e) : expr(e) {}
~AfterNode() { delete expr; }
~AfterNode()
{
delete expr;
}
ExprNode* semant(Environ* e);
TNode* translate(Codegen* g);
};
@@ -163,7 +213,10 @@ struct AfterNode : public ExprNode {
struct BeforeNode : public ExprNode {
ExprNode* expr;
BeforeNode(ExprNode* e) : expr(e) {}
~BeforeNode() { delete expr; }
~BeforeNode()
{
delete expr;
}
ExprNode* semant(Environ* e);
TNode* translate(Codegen* g);
};
@@ -177,7 +230,10 @@ struct ObjectCastNode : public ExprNode {
ExprNode* expr;
string type_ident;
ObjectCastNode(ExprNode* e, const string& t) : expr(e), type_ident(t) {}
~ObjectCastNode() { delete expr; }
~ObjectCastNode()
{
delete expr;
}
ExprNode* semant(Environ* e);
TNode* translate(Codegen* g);
};
@@ -185,7 +241,10 @@ struct ObjectCastNode : public ExprNode {
struct ObjectHandleNode : public ExprNode {
ExprNode* expr;
ObjectHandleNode(ExprNode* e) : expr(e) {}
~ObjectHandleNode() { delete expr; }
~ObjectHandleNode()
{
delete expr;
}
ExprNode* semant(Environ* e);
TNode* translate(Codegen* g);
};
+121 -50
View File
@@ -1,32 +1,37 @@
#include "std.hpp"
#include "nodes.hpp"
#include "std.hpp"
set<string> Node::usedfuncs;
///////////////////////////////
// generic exception thrower //
///////////////////////////////
void Node::ex(){
void Node::ex()
{
ex("INTERNAL COMPILER ERROR");
}
void Node::ex( const string &e ){
void Node::ex(const string& e)
{
throw Ex(e, -1, "");
}
void Node::ex( const string &e,int pos ){
void Node::ex(const string& e, int pos)
{
throw Ex(e, pos, "");
}
void Node::ex( const string &e,int pos,const string &f ){
void Node::ex(const string& e, int pos, const string& f)
{
throw Ex(e, pos, f);
}
///////////////////////////////
// Generate a local variable //
///////////////////////////////
VarNode *Node::genLocal( Environ *e,Type *ty ){
VarNode* Node::genLocal(Environ* e, Type* ty)
{
string t = genLabel();
Decl* d = e->decls->insertDecl(t, ty, DECL_LOCAL);
return new DeclVarNode(d);
@@ -35,19 +40,24 @@ VarNode *Node::genLocal( Environ *e,Type *ty ){
/////////////////////////////////////////////////
// if type is const, return const value else 0 //
/////////////////////////////////////////////////
ConstNode *Node::constValue( Type *ty ){
ConstNode* Node::constValue(Type* ty)
{
ConstType* c = ty->constType();
if( !c ) return 0;
if (!c)
return 0;
ty = c->valueType;
if( ty==Type::int_type ) return new IntConstNode( c->intValue );
if( ty==Type::float_type ) return new FloatConstNode( c->floatValue );
if (ty == Type::int_type)
return new IntConstNode(c->intValue);
if (ty == Type::float_type)
return new FloatConstNode(c->floatValue);
return new StringConstNode(c->stringValue);
}
///////////////////////////////////////////////////////
// work out var offsets - return size of local frame //
///////////////////////////////////////////////////////
int Node::enumVars( Environ *e ){
int Node::enumVars(Environ* e)
{
//calc offsets
int p_size = 0, l_size = 0;
for (int k = 0; k < e->decls->size(); ++k) {
@@ -66,15 +76,19 @@ int Node::enumVars( Environ *e ){
//////////////////////////////
// initialize all vars to 0 //
//////////////////////////////
TNode *Node::createVars( Environ *e ){
TNode* Node::createVars(Environ* e)
{
int k;
TNode* t = 0;
//initialize locals
for (k = 0; k < e->decls->size(); ++k) {
Decl* d = e->decls->decls[k];
if( d->kind!=DECL_LOCAL ) continue;
if( d->type->vectorType() ) continue;
if( !t ) t=new TNode( IR_CONST,0,0,0 );
if (d->kind != DECL_LOCAL)
continue;
if (d->type->vectorType())
continue;
if (!t)
t = new TNode(IR_CONST, 0, 0, 0);
TNode* p = new TNode(IR_LOCAL, 0, 0, d->offset);
p = new TNode(IR_MEM, p, 0);
t = new TNode(IR_MOVE, t, p);
@@ -82,14 +96,18 @@ TNode *Node::createVars( Environ *e ){
//initialize vectors
for (k = 0; k < e->decls->size(); ++k) {
Decl* d = e->decls->decls[k];
if( d->kind==DECL_PARAM ) continue;
if (d->kind == DECL_PARAM)
continue;
VectorType* v = d->type->vectorType();
if( !v ) continue;
if (!v)
continue;
TNode* p = call("__bbVecAlloc", global(v->label));
TNode* m = d->kind == DECL_GLOBAL ? global("_v" + d->name) : local(d->offset);
p = move(p, mem(m));
if( t ) t=seq( t,p );
else t=p;
if (t)
t = seq(t, p);
else
t = p;
}
return t;
}
@@ -97,7 +115,8 @@ TNode *Node::createVars( Environ *e ){
////////////////////////
// release local vars //
////////////////////////
TNode *Node::deleteVars( Environ *e ){
TNode* Node::deleteVars(Environ* e)
{
TNode *t = 0, *l = 0, *p, *p1 = nullptr, *p2 = nullptr;
for (int k = 0; k < e->decls->size(); ++k) {
Decl* d = e->decls->decls[k];
@@ -122,7 +141,8 @@ TNode *Node::deleteVars( Environ *e ){
p2 = global(v->label);
}
}
if( !func.size() ) continue;
if (!func.size())
continue;
p = new TNode(IR_SEQ, call(func, p1, p2), 0);
(l ? l->r : t) = p;
l = p;
@@ -133,19 +153,50 @@ TNode *Node::deleteVars( Environ *e ){
//////////////////////////////////////////////////////////////
// compare 2 translated operands - return 1 if true, else 0 //
//////////////////////////////////////////////////////////////
TNode *Node::compare( int op,TNode *l,TNode *r,Type *ty ){
TNode* Node::compare(int op, TNode* l, TNode* r, Type* ty)
{
int n = 0;
if (ty == Type::float_type) {
switch (op) {
case '=':n=IR_FSETEQ;break;case NE :n=IR_FSETNE;break;
case '<':n=IR_FSETLT;break;case '>':n=IR_FSETGT;break;
case LE :n=IR_FSETLE;break;case GE :n=IR_FSETGE;break;
case '=':
n = IR_FSETEQ;
break;
case NE:
n = IR_FSETNE;
break;
case '<':
n = IR_FSETLT;
break;
case '>':
n = IR_FSETGT;
break;
case LE:
n = IR_FSETLE;
break;
case GE:
n = IR_FSETGE;
break;
}
} else {
switch (op) {
case '=':n=IR_SETEQ;break;case NE :n=IR_SETNE;break;
case '<':n=IR_SETLT;break;case '>':n=IR_SETGT;break;
case LE :n=IR_SETLE;break;case GE :n=IR_SETGE;break;
case '=':
n = IR_SETEQ;
break;
case NE:
n = IR_SETNE;
break;
case '<':
n = IR_SETLT;
break;
case '>':
n = IR_SETGT;
break;
case LE:
n = IR_SETLE;
break;
case GE:
n = IR_SETGE;
break;
}
}
if (ty == Type::string_type) {
@@ -161,19 +212,23 @@ TNode *Node::compare( int op,TNode *l,TNode *r,Type *ty ){
/////////////////////////////////
// calculate the type of a tag //
/////////////////////////////////
Type *Node::tagType( const string &tag,Environ *e ){
Type* Node::tagType(const string& tag, Environ* e)
{
Type* t;
if (tag.size()) {
t = e->findType(tag);
if( !t ) ex( "Type \""+tag+"\" not found" );
}else t=0;
if (!t)
ex("Type \"" + tag + "\" not found");
} else
t = 0;
return t;
}
////////////////////////////////
// Generate a fresh ASM label //
////////////////////////////////
string Node::genLabel(){
string Node::genLabel()
{
static int cnt;
return "_" + itoa(++cnt & 0x7fffffff);
}
@@ -181,7 +236,8 @@ string Node::genLabel(){
//////////////////////////////////////////////////////
// create a stmt-type function call with int result //
//////////////////////////////////////////////////////
TNode *Node::call( const string &func,TNode *a0,TNode *a1,TNode *a2 ){
TNode* Node::call(const string& func, TNode* a0, TNode* a1, TNode* a2)
{
int size = 0;
TNode* t = 0;
if (a0) {
@@ -203,7 +259,8 @@ TNode *Node::call( const string &func,TNode *a0,TNode *a1,TNode *a2 ){
////////////////////////////////////////////////////////
// create a stmt-type function call with float result //
////////////////////////////////////////////////////////
TNode *Node::fcall( const string &func,TNode *a0,TNode *a1,TNode *a2 ){
TNode* Node::fcall(const string& func, TNode* a0, TNode* a1, TNode* a2)
{
int size = 0;
TNode* t = 0;
if (a0) {
@@ -222,63 +279,77 @@ TNode *Node::fcall( const string &func,TNode *a0,TNode *a1,TNode *a2 ){
return new TNode(IR_FCALL, l, t, size);
}
TNode *Node::seq( TNode *l,TNode *r ){
TNode* Node::seq(TNode* l, TNode* r)
{
return new TNode(IR_SEQ, l, r);
}
TNode *Node::move( TNode *src,TNode *dest ){
TNode* Node::move(TNode* src, TNode* dest)
{
return new TNode(IR_MOVE, src, dest);
}
TNode *Node::global( const string &s ){
TNode* Node::global(const string& s)
{
return new TNode(IR_GLOBAL, 0, 0, s);
}
TNode *Node::local( int offset ){
TNode* Node::local(int offset)
{
return new TNode(IR_LOCAL, 0, 0, offset);
}
TNode *Node::arg( int offset ){
TNode* Node::arg(int offset)
{
return new TNode(IR_ARG, 0, 0, offset);
}
TNode *Node::mem( TNode *ref ){
TNode* Node::mem(TNode* ref)
{
return new TNode(IR_MEM, ref, 0);
}
TNode *Node::add( TNode *l,TNode *r ){
TNode* Node::add(TNode* l, TNode* r)
{
return new TNode(IR_ADD, l, r);
}
TNode *Node::mul( TNode *l,TNode *r ){
TNode* Node::mul(TNode* l, TNode* r)
{
return new TNode(IR_MUL, l, r);
}
TNode *Node::iconst( int n ){
TNode* Node::iconst(int n)
{
return new TNode(IR_CONST, 0, 0, n);
}
TNode *Node::ret(){
TNode* Node::ret()
{
return new TNode(IR_RET, 0, 0);
}
TNode *Node::jsr( const string &s ){
TNode* Node::jsr(const string& s)
{
return new TNode(IR_JSR, 0, 0, s);
}
TNode *Node::jump( const string &s ){
TNode* Node::jump(const string& s)
{
return new TNode(IR_JUMP, 0, 0, s);
}
TNode *Node::jumpt( TNode *expr,const string &s ){
TNode* Node::jumpt(TNode* expr, const string& s)
{
return new TNode(IR_JUMPT, expr, 0, s);
}
TNode *Node::jumpf( TNode *expr,const string &s ){
TNode* Node::jumpf(TNode* expr, const string& s)
{
return new TNode(IR_JUMPF, expr, 0, s);
}
TNode *Node::jumpge( TNode *l,TNode *r,const string &s ){
TNode* Node::jumpge(TNode* l, TNode* r, const string& s)
{
return new TNode(IR_JUMPGE, l, r, s);
}
+2 -2
View File
@@ -2,10 +2,10 @@
#ifndef NODE_H
#define NODE_H
#include "codegen.hpp"
#include "environ.hpp"
#include "ex.hpp"
#include "toker.hpp"
#include "environ.hpp"
#include "codegen.hpp"
struct VarNode;
struct ConstNode;
+2 -2
View File
@@ -2,9 +2,9 @@
#ifndef NODES_H
#define NODES_H
#include "exprnode.hpp"
#include "stmtnode.hpp"
#include "declnode.hpp"
#include "exprnode.hpp"
#include "prognode.hpp"
#include "stmtnode.hpp"
#endif
+383 -240
View File
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -8,12 +8,11 @@
#ifndef PARSER_H
#define PARSER_H
#include "toker.hpp"
#include "nodes.hpp"
#include "toker.hpp"
class Parser {
public:
Parser(Toker& t);
ProgNode* parse(const string& main);
+15 -11
View File
@@ -1,12 +1,12 @@
#include "std.hpp"
#include "nodes.hpp"
#include "std.hpp"
//////////////////
// The program! //
//////////////////
Environ *ProgNode::semant( Environ *e ){
Environ* ProgNode::semant(Environ* e)
{
file_lab = genLabel();
StmtSeqNode::reset(stmts->file, file_lab);
@@ -26,11 +26,12 @@ Environ *ProgNode::semant( Environ *e ){
return sem_env;
}
void ProgNode::translate( Codegen *g,const vector<UserFunc> &usrfuncs ){
void ProgNode::translate(Codegen* g, const vector<UserFunc>& usrfuncs)
{
int k;
if( g->debug ) g->s_data( stmts->file,file_lab );
if (g->debug)
g->s_data(stmts->file, file_lab);
//enumerate locals
int size = enumVars(sem_env);
@@ -51,7 +52,8 @@ void ProgNode::translate( Codegen *g,const vector<UserFunc> &usrfuncs ){
//create locals
TNode* t = createVars(sem_env);
if( t ) g->code( t );
if (t)
g->code(t);
if (g->debug) {
string t = genLabel();
g->s_data("<main program>", t);
@@ -69,13 +71,15 @@ void ProgNode::translate( Codegen *g,const vector<UserFunc> &usrfuncs ){
//check labels
for (k = 0; k < sem_env->labels.size(); ++k) {
if( sem_env->labels[k]->def<0 ) ex( "Undefined label '"+sem_env->labels[k]->name+"'",sem_env->labels[k]->ref,stmts->file );
if (sem_env->labels[k]->def < 0)
ex("Undefined label '" + sem_env->labels[k]->name + "'", sem_env->labels[k]->ref, stmts->file);
}
//leave main program
g->label(sem_env->funcLabel + "_leave");
t = deleteVars(sem_env);
if( g->debug ) t=new TNode( IR_SEQ,call( "__bbDebugLeave" ),t );
if (g->debug)
t = new TNode(IR_SEQ, call("__bbDebugLeave"), t);
g->leave(t, 0);
//structs
@@ -96,7 +100,8 @@ void ProgNode::translate( Codegen *g,const vector<UserFunc> &usrfuncs ){
for (k = 0; k < usrfuncs.size(); ++k) {
const UserFunc& fn = usrfuncs[k];
if( !usedfuncs.count(fn.ident) ) continue;
if (!usedfuncs.count(fn.ident))
continue;
libFuncs[fn.lib].push_back(k);
@@ -108,7 +113,6 @@ void ProgNode::translate( Codegen *g,const vector<UserFunc> &usrfuncs ){
g->label("__LIBS");
map<string, vector<int>>::const_iterator lf_it;
for (lf_it = libFuncs.begin(); lf_it != libFuncs.end(); ++lf_it) {
//lib name
g->s_data(lf_it->first);
+6 -4
View File
@@ -2,8 +2,8 @@
#ifndef PROGNODE_H
#define PROGNODE_H
#include "node.hpp"
#include "codegen.hpp"
#include "node.hpp"
struct UserFunc {
string ident, proc, lib;
@@ -12,7 +12,6 @@ struct UserFunc{
};
struct ProgNode : public Node {
DeclSeqNode* consts;
DeclSeqNode* structs;
DeclSeqNode* funcs;
@@ -23,8 +22,11 @@ struct ProgNode : public Node{
string file_lab;
ProgNode( DeclSeqNode *c,DeclSeqNode *s,DeclSeqNode *f,DeclSeqNode *d,StmtSeqNode *ss ):consts(c),structs(s),funcs(f),datas(d),stmts(ss){}
~ProgNode(){
ProgNode(DeclSeqNode* c, DeclSeqNode* s, DeclSeqNode* f, DeclSeqNode* d, StmtSeqNode* ss)
: consts(c), structs(s), funcs(f), datas(d), stmts(ss)
{}
~ProgNode()
{
delete consts;
delete structs;
delete funcs;
+5 -5
View File
@@ -5,14 +5,14 @@
#include "config.hpp"
#include "stdutil.hpp"
#include <set>
#include <map>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <iomanip>
using namespace std;
+208 -112
View File
@@ -1,18 +1,20 @@
#include "std.hpp"
#include "nodes.hpp"
#include "std.hpp"
static string fileLabel;
static map<string, string> fileMap;
void StmtNode::debug(int pos, Codegen *g) {
void StmtNode::debug(int pos, Codegen* g)
{
if (g->debug) {
TNode* t = fileLabel.size() ? global(fileLabel) : iconst(0);
g->code(call("__bbDebugStmt", iconst(pos), t));
}
}
void StmtSeqNode::reset(const string &file, const string &lab) {
void StmtSeqNode::reset(const string& file, const string& lab)
{
fileLabel = "";
fileMap.clear();
@@ -22,18 +24,23 @@ void StmtSeqNode::reset(const string &file, const string &lab) {
////////////////////////
// Statement Sequence //
////////////////////////
void StmtSeqNode::semant(Environ *e) {
void StmtSeqNode::semant(Environ* e)
{
for (int k = 0; k < stmts.size(); ++k) {
try { stmts[k]->semant(e); } catch (Ex &x) {
if (x.pos < 0) x.pos = stmts[k]->pos;
if (!x.file.size()) x.file = file;
try {
stmts[k]->semant(e);
} catch (Ex& x) {
if (x.pos < 0)
x.pos = stmts[k]->pos;
if (!x.file.size())
x.file = file;
throw;
}
}
}
void StmtSeqNode::translate(Codegen *g) {
void StmtSeqNode::translate(Codegen* g)
{
string t = fileLabel;
fileLabel = file.size() ? fileMap[file] : "";
for (int k = 0; k < stmts.size(); ++k) {
@@ -42,8 +49,10 @@ void StmtSeqNode::translate(Codegen *g) {
try {
stmt->translate(g);
} catch (Ex& x) {
if (x.pos < 0) x.pos = stmts[k]->pos;
if (!x.file.size()) x.file = file;
if (x.pos < 0)
x.pos = stmts[k]->pos;
if (!x.file.size())
x.file = file;
throw;
}
}
@@ -53,17 +62,18 @@ void StmtSeqNode::translate(Codegen *g) {
/////////////////
// An Include! //
/////////////////
void IncludeNode::semant(Environ *e) {
void IncludeNode::semant(Environ* e)
{
label = genLabel();
fileMap[file] = label;
stmts->semant(e);
}
void IncludeNode::translate(Codegen *g) {
if (g->debug) g->s_data(file, label);
void IncludeNode::translate(Codegen* g)
{
if (g->debug)
g->s_data(file, label);
stmts->translate(g);
}
@@ -71,29 +81,35 @@ void IncludeNode::translate(Codegen *g) {
///////////////////
// a declaration //
///////////////////
void DeclStmtNode::semant(Environ *e) {
void DeclStmtNode::semant(Environ* e)
{
decl->proto(e->decls, e);
decl->semant(e);
}
void DeclStmtNode::translate(Codegen *g) {
void DeclStmtNode::translate(Codegen* g)
{
decl->translate(g);
}
//////////////////////////////
// Dim AND declare an Array //
//////////////////////////////
void DimNode::semant(Environ *e) {
void DimNode::semant(Environ* e)
{
Type* t = tagType(tag, e);
if (Decl* d = e->findDecl(ident)) {
ArrayType* a = d->type->arrayType();
if (!a || a->dims != exprs->size() || (t && a->elementType != t)) {
ex("Duplicate identifier");
}
sem_type = a; sem_decl = 0;
sem_type = a;
sem_decl = 0;
} else {
if (e->level > 0) ex("Array not found in main program");
if (!t) t = Type::int_type;
if (e->level > 0)
ex("Array not found in main program");
if (!t)
t = Type::int_type;
sem_type = new ArrayType(t, exprs->size());
sem_decl = e->decls->insertDecl(ident, sem_type, DECL_ARRAY);
e->types.push_back(sem_type);
@@ -102,7 +118,8 @@ void DimNode::semant(Environ *e) {
exprs->castTo(Type::int_type, e);
}
void DimNode::translate(Codegen *g) {
void DimNode::translate(Codegen* g)
{
TNode* t;
g->code(call("__bbUndimArray", global("_a" + ident)));
for (int k = 0; k < exprs->size(); ++k) {
@@ -112,125 +129,160 @@ void DimNode::translate(Codegen *g) {
}
g->code(call("__bbDimArray", global("_a" + ident)));
if (!sem_decl) return;
if (!sem_decl)
return;
int et, k;
Type* ty = sem_type->arrayType()->elementType;
if (ty == Type::int_type) et = 1;
else if (ty == Type::float_type) et = 2;
else if (ty == Type::string_type) et = 3;
else et = 5;
if (ty == Type::int_type)
et = 1;
else if (ty == Type::float_type)
et = 2;
else if (ty == Type::string_type)
et = 3;
else
et = 5;
g->align_data(4);
g->i_data(0, "_a" + ident);
g->i_data(et);
g->i_data(exprs->size());
for (k = 0; k < exprs->size(); ++k) g->i_data(0);
for (k = 0; k < exprs->size(); ++k)
g->i_data(0);
}
////////////////
// Assignment //
////////////////
void AssNode::semant(Environ *e) {
void AssNode::semant(Environ* e)
{
var->semant(e);
if (var->sem_type->constType()) ex("Constants can not be assigned to");
if (var->sem_type->vectorType()) ex("Blitz arrays can not be assigned to");
if (var->sem_type->constType())
ex("Constants can not be assigned to");
if (var->sem_type->vectorType())
ex("Blitz arrays can not be assigned to");
expr = expr->semant(e);
expr = expr->castTo(var->sem_type, e);
}
void AssNode::translate(Codegen *g) {
void AssNode::translate(Codegen* g)
{
g->code(var->store(g, expr->translate(g)));
}
//////////////////////////
// Expression statement //
//////////////////////////
void ExprStmtNode::semant(Environ *e) {
void ExprStmtNode::semant(Environ* e)
{
expr = expr->semant(e);
}
void ExprStmtNode::translate(Codegen *g) {
void ExprStmtNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
if (expr->sem_type == Type::string_type) t = call("__bbStrRelease", t);
if (expr->sem_type == Type::string_type)
t = call("__bbStrRelease", t);
g->code(t);
}
////////////////
// user label //
////////////////
void LabelNode::semant(Environ *e) {
void LabelNode::semant(Environ* e)
{
if (Label* l = e->findLabel(ident)) {
if (l->def >= 0) ex("duplicate label");
l->def = pos; l->data_sz = data_sz;
} else e->insertLabel(ident, pos, -1, data_sz);
if (l->def >= 0)
ex("duplicate label");
l->def = pos;
l->data_sz = data_sz;
} else
e->insertLabel(ident, pos, -1, data_sz);
ident = e->funcLabel + ident;
}
void LabelNode::translate(Codegen *g) {
void LabelNode::translate(Codegen* g)
{
g->label("_l" + ident);
}
//////////////////
// Restore data //
//////////////////
void RestoreNode::semant(Environ *e) {
if (e->level > 0) e = e->globals;
void RestoreNode::semant(Environ* e)
{
if (e->level > 0)
e = e->globals;
if (ident.size() == 0) sem_label = 0;
if (ident.size() == 0)
sem_label = 0;
else {
sem_label = e->findLabel(ident);
if (!sem_label) sem_label = e->insertLabel(ident, -1, pos, -1);
if (!sem_label)
sem_label = e->insertLabel(ident, -1, pos, -1);
}
}
void RestoreNode::translate(Codegen *g) {
void RestoreNode::translate(Codegen* g)
{
TNode* t = global("__DATA");
if (sem_label) t = add(t, iconst(sem_label->data_sz * 8));
if (sem_label)
t = add(t, iconst(sem_label->data_sz * 8));
g->code(call("__bbRestore", t));
}
////////////////////
// Goto statement //
////////////////////
void GotoNode::semant(Environ *e) {
void GotoNode::semant(Environ* e)
{
if (!e->findLabel(ident)) {
e->insertLabel(ident, -1, pos, -1);
}
ident = e->funcLabel + ident;
}
void GotoNode::translate(Codegen *g) {
void GotoNode::translate(Codegen* g)
{
g->code(jump("_l" + ident));
}
/////////////////////
// Gosub statement //
/////////////////////
void GosubNode::semant(Environ *e) {
if (e->level > 0) ex("'Gosub' may not be used inside a function");
if (!e->findLabel(ident)) e->insertLabel(ident, -1, pos, -1);
void GosubNode::semant(Environ* e)
{
if (e->level > 0)
ex("'Gosub' may not be used inside a function");
if (!e->findLabel(ident))
e->insertLabel(ident, -1, pos, -1);
ident = e->funcLabel + ident;
}
void GosubNode::translate(Codegen *g) {
void GosubNode::translate(Codegen* g)
{
g->code(jsr("_l" + ident));
}
//////////////////
// If statement //
//////////////////
void IfNode::semant(Environ *e) {
void IfNode::semant(Environ* e)
{
expr = expr->semant(e);
expr = expr->castTo(Type::int_type, e);
stmts->semant(e);
if (elseOpt) elseOpt->semant(e);
if (elseOpt)
elseOpt->semant(e);
}
void IfNode::translate(Codegen *g) {
void IfNode::translate(Codegen* g)
{
if (ConstNode* c = expr->constNode()) {
if (c->intValue()) stmts->translate(g);
else if (elseOpt) elseOpt->translate(g);
if (c->intValue())
stmts->translate(g);
else if (elseOpt)
elseOpt->translate(g);
} else {
string _else = genLabel();
g->code(jumpf(expr->translate(g), _else));
@@ -249,19 +301,23 @@ void IfNode::translate(Codegen *g) {
///////////
// Break //
///////////
void ExitNode::semant(Environ *e) {
void ExitNode::semant(Environ* e)
{
sem_brk = e->breakLabel;
if (!sem_brk.size()) ex("break must appear inside a loop");
if (!sem_brk.size())
ex("break must appear inside a loop");
}
void ExitNode::translate(Codegen *g) {
void ExitNode::translate(Codegen* g)
{
g->code(new TNode(IR_JUMP, 0, 0, sem_brk));
}
/////////////////////
// While statement //
/////////////////////
void WhileNode::semant(Environ *e) {
void WhileNode::semant(Environ* e)
{
expr = expr->semant(e);
expr = expr->castTo(Type::int_type, e);
string brk = e->setBreak(sem_brk = genLabel());
@@ -269,10 +325,12 @@ void WhileNode::semant(Environ *e) {
e->setBreak(brk);
}
void WhileNode::translate(Codegen *g) {
void WhileNode::translate(Codegen* g)
{
string loop = genLabel();
if (ConstNode* c = expr->constNode()) {
if (!c->intValue()) return;
if (!c->intValue())
return;
g->label(loop);
stmts->translate(g);
g->code(jump(loop));
@@ -292,10 +350,11 @@ void WhileNode::translate(Codegen *g) {
// For/Next loop //
///////////////////
ForNode::ForNode(VarNode* var, ExprNode* from, ExprNode* to, ExprNode* step, StmtSeqNode* ss, int np)
:var(var), fromExpr(from), toExpr(to), stepExpr(step), stmts(ss), nextPos(np) {
}
: var(var), fromExpr(from), toExpr(to), stepExpr(step), stmts(ss), nextPos(np)
{}
ForNode::~ForNode() {
ForNode::~ForNode()
{
delete stmts;
delete stepExpr;
delete toExpr;
@@ -303,10 +362,12 @@ ForNode::~ForNode() {
delete var;
}
void ForNode::semant(Environ *e) {
void ForNode::semant(Environ* e)
{
var->semant(e);
Type* ty = var->sem_type;
if (ty->constType()) ex("Index variable can not be constant");
if (ty->constType())
ex("Index variable can not be constant");
if (ty != Type::int_type && ty != Type::float_type) {
ex("index variable must be integer or real");
}
@@ -317,16 +378,18 @@ void ForNode::semant(Environ *e) {
stepExpr = stepExpr->semant(e);
stepExpr = stepExpr->castTo(ty, e);
if (!stepExpr->constNode()) ex("Step value must be constant");
if (!stepExpr->constNode())
ex("Step value must be constant");
string brk = e->setBreak(sem_brk = genLabel());
stmts->semant(e);
e->setBreak(brk);
}
void ForNode::translate(Codegen *g) {
TNode *t; Type *ty = var->sem_type;
void ForNode::translate(Codegen* g)
{
TNode* t;
Type* ty = var->sem_type;
//initial assignment
g->code(var->store(g, fromExpr->translate(g)));
@@ -355,21 +418,26 @@ void ForNode::translate(Codegen *g) {
///////////////////////////////
// For each object of a type //
///////////////////////////////
void ForEachNode::semant(Environ *e) {
void ForEachNode::semant(Environ* e)
{
var->semant(e);
Type* ty = var->sem_type;
if (ty->structType() == 0) ex("Index variable is not a NewType");
if (ty->structType() == 0)
ex("Index variable is not a NewType");
Type* t = e->findType(typeIdent);
if (!t) ex("Type name not found");
if (t != ty) ex("Type mismatch");
if (!t)
ex("Type name not found");
if (t != ty)
ex("Type mismatch");
string brk = e->setBreak(sem_brk = genLabel());
stmts->semant(e);
e->setBreak(brk);
}
void ForEachNode::translate(Codegen *g) {
void ForEachNode::translate(Codegen* g)
{
TNode *t, *l, *r;
string _loop = genLabel();
@@ -401,7 +469,8 @@ void ForEachNode::translate(Codegen *g) {
////////////////////////////
// Return from a function //
////////////////////////////
void ReturnNode::semant(Environ *e) {
void ReturnNode::semant(Environ* e)
{
if (e->level <= 0 && expr) {
ex("Main program cannot return a value");
}
@@ -423,7 +492,8 @@ void ReturnNode::semant(Environ *e) {
}
}
void ReturnNode::translate(Codegen *g) {
void ReturnNode::translate(Codegen* g)
{
if (!expr) {
g->code(new TNode(IR_RET, 0, 0));
return;
@@ -441,12 +511,15 @@ void ReturnNode::translate(Codegen *g) {
//////////////////////
// Delete statement //
//////////////////////
void DeleteNode::semant(Environ *e) {
void DeleteNode::semant(Environ* e)
{
expr = expr->semant(e);
if (expr->sem_type->structType() == 0) ex("Can't delete non-Newtype");
if (expr->sem_type->structType() == 0)
ex("Can't delete non-Newtype");
}
void DeleteNode::translate(Codegen *g) {
void DeleteNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
g->code(call("__bbObjDelete", t));
}
@@ -454,32 +527,41 @@ void DeleteNode::translate(Codegen *g) {
///////////////////////////
// Delete each of a type //
///////////////////////////
void DeleteEachNode::semant(Environ *e) {
void DeleteEachNode::semant(Environ* e)
{
Type* t = e->findType(typeIdent);
if (!t || t->structType() == 0) ex("Specified name is not a NewType name");
if (!t || t->structType() == 0)
ex("Specified name is not a NewType name");
}
void DeleteEachNode::translate(Codegen *g) {
void DeleteEachNode::translate(Codegen* g)
{
g->code(call("__bbObjDeleteEach", global("_t" + typeIdent)));
}
///////////////////////////
// Insert object in list //
///////////////////////////
void InsertNode::semant(Environ *e) {
void InsertNode::semant(Environ* e)
{
expr1 = expr1->semant(e);
expr2 = expr2->semant(e);
StructType* t1 = expr1->sem_type->structType();
StructType* t2 = expr2->sem_type->structType();
if (!t1 || !t2) ex("Illegal expression type");
if (t1 != t2) ex("Objects types are differnt");
if (!t1 || !t2)
ex("Illegal expression type");
if (t1 != t2)
ex("Objects types are differnt");
}
void InsertNode::translate(Codegen *g) {
void InsertNode::translate(Codegen* g)
{
TNode* t1 = expr1->translate(g);
if (g->debug) t1 = jumpf(t1, "__bbNullObjEx");
if (g->debug)
t1 = jumpf(t1, "__bbNullObjEx");
TNode* t2 = expr2->translate(g);
if (g->debug) t2 = jumpf(t2, "__bbNullObjEx");
if (g->debug)
t2 = jumpf(t2, "__bbNullObjEx");
string s = before ? "__bbObjInsBefore" : "__bbObjInsAfter";
g->code(call(s, t1, t2));
}
@@ -487,10 +569,12 @@ void InsertNode::translate(Codegen *g) {
////////////////////////
// A select statement //
////////////////////////
void SelectNode::semant(Environ *e) {
void SelectNode::semant(Environ* e)
{
expr = expr->semant(e);
Type* ty = expr->sem_type;
if (ty->structType()) ex("Select cannot be used with objects");
if (ty->structType())
ex("Select cannot be used with objects");
//we need a temp var
Decl* d = e->decls->insertDecl(genLabel(), expr->sem_type, DECL_LOCAL);
@@ -502,11 +586,12 @@ void SelectNode::semant(Environ *e) {
c->exprs->castTo(ty, e);
c->stmts->semant(e);
}
if (defStmts) defStmts->semant(e);
if (defStmts)
defStmts->semant(e);
}
void SelectNode::translate(Codegen *g) {
void SelectNode::translate(Codegen* g)
{
Type* ty = expr->sem_type;
int k;
@@ -524,7 +609,8 @@ void SelectNode::translate(Codegen *g) {
g->code(jumpt(t, labs.back()));
}
}
if (defStmts) defStmts->translate(g);
if (defStmts)
defStmts->translate(g);
g->code(jump(brk));
for (k = 0; k < cases.size(); ++k) {
CaseNode* c = cases[k];
@@ -539,7 +625,8 @@ void SelectNode::translate(Codegen *g) {
////////////////////////////
// Repeat...Until/Forever //
////////////////////////////
void RepeatNode::semant(Environ *e) {
void RepeatNode::semant(Environ* e)
{
sem_brk = genLabel();
string brk = e->setBreak(sem_brk);
stmts->semant(e);
@@ -550,18 +637,21 @@ void RepeatNode::semant(Environ *e) {
}
}
void RepeatNode::translate(Codegen *g) {
void RepeatNode::translate(Codegen* g)
{
string loop = genLabel();
g->label(loop);
stmts->translate(g);
debug(untilPos, g);
if (ConstNode* c = expr ? expr->constNode() : 0) {
if (!c->intValue()) g->code(jump(loop));
if (!c->intValue())
g->code(jump(loop));
} else {
if (expr) g->code(jumpf(expr->translate(g), loop));
else g->code(jump(loop));
if (expr)
g->code(jumpf(expr->translate(g), loop));
else
g->code(jump(loop));
}
g->label(sem_brk);
}
@@ -569,17 +659,23 @@ void RepeatNode::translate(Codegen *g) {
///////////////
// Read data //
///////////////
void ReadNode::semant(Environ *e) {
void ReadNode::semant(Environ* e)
{
var->semant(e);
if (var->sem_type->constType()) ex("Constants can not be modified");
if (var->sem_type->structType()) ex("Data can not be read into an object");
if (var->sem_type->constType())
ex("Constants can not be modified");
if (var->sem_type->structType())
ex("Data can not be read into an object");
}
void ReadNode::translate(Codegen *g) {
void ReadNode::translate(Codegen* g)
{
TNode* t;
if (var->sem_type == Type::int_type) t = call("__bbReadInt");
else if (var->sem_type == Type::float_type) t = fcall("__bbReadFloat");
else t = call("__bbReadStr");
if (var->sem_type == Type::int_type)
t = call("__bbReadInt");
else if (var->sem_type == Type::float_type)
t = fcall("__bbReadFloat");
else
t = call("__bbReadStr");
g->code(var->store(g, t));
}
+94 -21
View File
@@ -17,23 +17,36 @@ struct StmtSeqNode : public Node{
string file;
vector<StmtNode*> stmts;
StmtSeqNode(const string& f) : file(f) {}
~StmtSeqNode(){ for( ;stmts.size();stmts.pop_back() ) delete stmts.back(); }
~StmtSeqNode()
{
for (; stmts.size(); stmts.pop_back())
delete stmts.back();
}
void semant(Environ* e);
void translate(Codegen* g);
void push_back( StmtNode *s ){ stmts.push_back( s ); }
int size(){ return stmts.size(); }
void push_back(StmtNode* s)
{
stmts.push_back(s);
}
int size()
{
return stmts.size();
}
static void reset(const string& file, const string& lab);
};
#include "exprnode.hpp"
#include "declnode.hpp"
#include "exprnode.hpp"
struct IncludeNode : public StmtNode {
string file, label;
StmtSeqNode* stmts;
IncludeNode(const string& t, StmtSeqNode* ss) : file(t), stmts(ss) {}
~IncludeNode(){ delete stmts; }
~IncludeNode()
{
delete stmts;
}
void semant(Environ* e);
void translate(Codegen* g);
@@ -41,8 +54,14 @@ struct IncludeNode : public StmtNode{
struct DeclStmtNode : public StmtNode {
DeclNode* decl;
DeclStmtNode( DeclNode *d ):decl(d){ pos=d->pos; }
~DeclStmtNode(){ delete decl; }
DeclStmtNode(DeclNode* d) : decl(d)
{
pos = d->pos;
}
~DeclStmtNode()
{
delete decl;
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -53,7 +72,10 @@ struct DimNode : public StmtNode{
ArrayType* sem_type;
Decl* sem_decl;
DimNode(const string& i, const string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {}
~DimNode(){ delete exprs; }
~DimNode()
{
delete exprs;
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -62,7 +84,11 @@ struct AssNode : public StmtNode{
VarNode* var;
ExprNode* expr;
AssNode(VarNode* var, ExprNode* expr) : var(var), expr(expr) {}
~AssNode(){ delete var;delete expr; }
~AssNode()
{
delete var;
delete expr;
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -70,7 +96,10 @@ struct AssNode : public StmtNode{
struct ExprStmtNode : public StmtNode {
ExprNode* expr;
ExprStmtNode(ExprNode* e) : expr(e) {}
~ExprStmtNode(){ delete expr; }
~ExprStmtNode()
{
delete expr;
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -101,7 +130,12 @@ struct IfNode : public StmtNode{
ExprNode* expr;
StmtSeqNode *stmts, *elseOpt;
IfNode(ExprNode* e, StmtSeqNode* s, StmtSeqNode* o) : expr(e), stmts(s), elseOpt(o) {}
~IfNode(){ delete expr;delete stmts;delete elseOpt; }
~IfNode()
{
delete expr;
delete stmts;
delete elseOpt;
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -118,7 +152,11 @@ struct WhileNode : public StmtNode{
StmtSeqNode* stmts;
string sem_brk;
WhileNode(ExprNode* e, StmtSeqNode* s, int wp) : expr(e), stmts(s), wendPos(wp) {}
~WhileNode(){ delete expr;delete stmts; }
~WhileNode()
{
delete expr;
delete stmts;
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -142,7 +180,11 @@ struct ForEachNode : public StmtNode{
StmtSeqNode* stmts;
string sem_brk;
ForEachNode(VarNode* v, const string& t, StmtSeqNode* s, int np) : var(v), typeIdent(t), stmts(s), nextPos(np) {}
~ForEachNode(){ delete var;delete stmts; }
~ForEachNode()
{
delete var;
delete stmts;
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -151,7 +193,10 @@ struct ReturnNode : public StmtNode{
ExprNode* expr;
string returnLabel;
ReturnNode(ExprNode* e) : expr(e) {}
~ReturnNode(){ delete expr; }
~ReturnNode()
{
delete expr;
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -159,7 +204,10 @@ struct ReturnNode : public StmtNode{
struct DeleteNode : public StmtNode {
ExprNode* expr;
DeleteNode(ExprNode* e) : expr(e) {}
~DeleteNode(){ delete expr; }
~DeleteNode()
{
delete expr;
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -175,7 +223,11 @@ struct InsertNode : public StmtNode{
ExprNode *expr1, *expr2;
bool before;
InsertNode(ExprNode* e1, ExprNode* e2, bool b) : expr1(e1), expr2(e2), before(b) {}
~InsertNode(){ delete expr1;delete expr2; }
~InsertNode()
{
delete expr1;
delete expr2;
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -184,7 +236,11 @@ struct CaseNode : public Node{
ExprSeqNode* exprs;
StmtSeqNode* stmts;
CaseNode(ExprSeqNode* e, StmtSeqNode* s) : exprs(e), stmts(s) {}
~CaseNode(){ delete exprs;delete stmts; }
~CaseNode()
{
delete exprs;
delete stmts;
}
};
struct SelectNode : public StmtNode {
@@ -193,8 +249,18 @@ struct SelectNode : public StmtNode{
vector<CaseNode*> cases;
VarNode* sem_temp;
SelectNode(ExprNode* e) : expr(e), defStmts(0), sem_temp(0) {}
~SelectNode(){ delete expr;delete defStmts;delete sem_temp;for( ;cases.size();cases.pop_back() ) delete cases.back(); }
void push_back( CaseNode *c ){ cases.push_back( c ); }
~SelectNode()
{
delete expr;
delete defStmts;
delete sem_temp;
for (; cases.size(); cases.pop_back())
delete cases.back();
}
void push_back(CaseNode* c)
{
cases.push_back(c);
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -205,7 +271,11 @@ struct RepeatNode : public StmtNode{
ExprNode* expr;
string sem_brk;
RepeatNode(StmtSeqNode* s, ExprNode* e, int up) : stmts(s), expr(e), untilPos(up) {}
~RepeatNode(){ delete stmts;delete expr; }
~RepeatNode()
{
delete stmts;
delete expr;
}
void semant(Environ* e);
void translate(Codegen* g);
};
@@ -213,7 +283,10 @@ struct RepeatNode : public StmtNode{
struct ReadNode : public StmtNode {
VarNode* var;
ReadNode(VarNode* v) : var(v) {}
~ReadNode(){ delete var; }
~ReadNode()
{
delete var;
}
void semant(Environ* e);
void translate(Codegen* g);
};
+58 -29
View File
@@ -1,16 +1,18 @@
#include "std.hpp"
#include <cctype>
#include "toker.hpp"
#include <cctype>
#include "ex.hpp"
#include "std.hpp"
int Toker::chars_toked;
static map<string, int> alphaTokes, lowerTokes;
static void makeKeywords(){
static void makeKeywords()
{
static bool made;
if( made ) return;
if (made)
return;
alphaTokes["Dim"] = DIM;
alphaTokes["Goto"] = GOTO;
@@ -86,44 +88,53 @@ static void makeKeywords(){
made = true;
}
Toker::Toker( istream &in ):in(in),curr_row(-1){
Toker::Toker(istream& in) : in(in), curr_row(-1)
{
makeKeywords();
nextline();
}
map<string,int> &Toker::getKeywords(){
map<string, int>& Toker::getKeywords()
{
makeKeywords();
return alphaTokes;
}
int Toker::pos(){
int Toker::pos()
{
return ((curr_row) << 16) | (tokes[curr_toke].from);
}
int Toker::curr(){
int Toker::curr()
{
return tokes[curr_toke].n;
}
string Toker::text(){
string Toker::text()
{
int from = tokes[curr_toke].from, to = tokes[curr_toke].to;
return line.substr(from, to - from);
}
int Toker::lookAhead( int n ){
int Toker::lookAhead(int n)
{
return tokes[curr_toke + n].n;
}
void Toker::nextline(){
void Toker::nextline()
{
++curr_row;
curr_toke = 0;
tokes.clear();
if (in.eof()) {
line.resize(1);line[0]=EOF;
line.resize(1);
line[0] = EOF;
tokes.push_back(Toke(EOF, 0, 1));
return;
}
getline( in,line );line+='\n';
getline(in, line);
line += '\n';
chars_toked += line.size();
for (int k = 0; k < line.size();) {
@@ -132,20 +143,27 @@ void Toker::nextline(){
tokes.push_back(Toke(c, from, ++k));
continue;
}
if( isspace( c ) ){ ++k;continue; }
if (isspace(c)) {
++k;
continue;
}
if (c == ';') {
for( ++k;line[k]!='\n';++k ){}
for (++k; line[k] != '\n'; ++k) {
}
continue;
}
if (c == '.' && isdigit(line[k + 1])) {
for( k+=2;isdigit( line[k] );++k ){}
for (k += 2; isdigit(line[k]); ++k) {
}
tokes.push_back(Toke(FLOATCONST, from, k));
continue;
}
if (isdigit(c)) {
for( ++k;isdigit( line[k] );++k ){}
for (++k; isdigit(line[k]); ++k) {
}
if (line[k] == '.') {
for( ++k;isdigit( line[k] );++k ){}
for (++k; isdigit(line[k]); ++k) {
}
tokes.push_back(Toke(FLOATCONST, from, k));
continue;
}
@@ -153,33 +171,39 @@ void Toker::nextline(){
continue;
}
if (c == '%' && (line[k + 1] == '0' || line[k + 1] == '1')) {
for( k+=2;line[k]=='0'||line[k]=='1';++k ){}
for (k += 2; line[k] == '0' || line[k] == '1'; ++k) {
}
tokes.push_back(Toke(BINCONST, from, k));
continue;
}
if (c == '$' && isxdigit(line[k + 1])) {
for( k+=2;isxdigit( line[k] );++k ){}
for (k += 2; isxdigit(line[k]); ++k) {
}
tokes.push_back(Toke(HEXCONST, from, k));
continue;
}
if (isalpha(c)) {
for( ++k;isalnum( line[k] ) || line[k]=='_';++k ){}
for (++k; isalnum(line[k]) || line[k] == '_'; ++k) {
}
string ident = tolower(line.substr(from, k - from));
if (line[k] == ' ' && isalpha(line[k + 1])) {
int t = k;
for( t+=2;isalnum( line[t] ) || line[t]=='_';++t ){}
for (t += 2; isalnum(line[t]) || line[t] == '_'; ++t) {
}
string s = tolower(line.substr(from, t - from));
if (lowerTokes.find(s) != lowerTokes.end()) {
k=t;ident=s;
k = t;
ident = s;
}
}
map<string, int>::iterator it = lowerTokes.find(ident);
if (it == lowerTokes.end()) {
for( int n=from;n<k;++n ) line[n]=tolower(line[n]);
for (int n = from; n < k; ++n)
line[n] = tolower(line[n]);
tokes.push_back(Toke(IDENT, from, k));
continue;
}
@@ -188,8 +212,10 @@ void Toker::nextline(){
continue;
}
if (c == '\"') {
for( ++k;line[k]!='\"' && line[k]!='\n';++k ){}
if( line[k]=='\"' ) ++k;
for (++k; line[k] != '\"' && line[k] != '\n'; ++k) {
}
if (line[k] == '\"')
++k;
tokes.push_back(Toke(STRINGCONST, from, k));
continue;
}
@@ -208,10 +234,13 @@ void Toker::nextline(){
}
tokes.push_back(Toke(c, from, ++k));
}
if( !tokes.size() ) exit(0);
if (!tokes.size())
exit(0);
}
int Toker::next(){
if( ++curr_toke==tokes.size() ) nextline();
int Toker::next()
{
if (++curr_toke == tokes.size())
nextline();
return curr();
}
+70 -18
View File
@@ -9,27 +9,79 @@
#define TOKER_H
enum {
DIM=0x8000,GOTO,GOSUB,EXIT,RETURN,
IF,THEN,ELSE,ENDIF,ELSEIF,
WHILE,WEND,
FOR,TO,STEP,NEXT,
FUNCTION,ENDFUNCTION,
TYPE,ENDTYPE,EACH,
GLOBAL,LOCAL,FIELD,BBCONST,
SELECT,CASE,DEFAULT,ENDSELECT,
REPEAT,UNTIL,FOREVER,
DATA,READ,RESTORE,
ABS,SGN,MOD,
PI,BBTRUE,BBFALSE,
BBINT,BBFLOAT,BBSTR,
DIM = 0x8000,
GOTO,
GOSUB,
EXIT,
RETURN,
IF,
THEN,
ELSE,
ENDIF,
ELSEIF,
WHILE,
WEND,
FOR,
TO,
STEP,
NEXT,
FUNCTION,
ENDFUNCTION,
TYPE,
ENDTYPE,
EACH,
GLOBAL,
LOCAL,
FIELD,
BBCONST,
SELECT,
CASE,
DEFAULT,
ENDSELECT,
REPEAT,
UNTIL,
FOREVER,
DATA,
READ,
RESTORE,
ABS,
SGN,
MOD,
PI,
BBTRUE,
BBFALSE,
BBINT,
BBFLOAT,
BBSTR,
INCLUDE,
BBNEW,BBDELETE,FIRST,LAST,INSERT,BEFORE,AFTER,BBNULL,
OBJECT,BBHANDLE,
AND,OR,XOR,NOT,SHL,SHR,SAR,
BBNEW,
BBDELETE,
FIRST,
LAST,
INSERT,
BEFORE,
AFTER,
BBNULL,
OBJECT,
BBHANDLE,
AND,
OR,
XOR,
NOT,
SHL,
SHR,
SAR,
LE,GE,NE,
IDENT,INTCONST,BINCONST,HEXCONST,FLOATCONST,STRINGCONST
LE,
GE,
NE,
IDENT,
INTCONST,
BINCONST,
HEXCONST,
FLOATCONST,
STRINGCONST
};
class Toker {
+27 -14
View File
@@ -1,51 +1,64 @@
#include "std.hpp"
#include "type.hpp"
#include "std.hpp"
static struct v_type : public Type {
bool canCastTo( Type *t ){
bool canCastTo(Type* t)
{
return t == Type::void_type;
}
} v;
static struct i_type : public Type {
bool intType(){
bool intType()
{
return true;
}
bool canCastTo( Type *t ){
bool canCastTo(Type* t)
{
return t == Type::int_type || t == Type::float_type || t == Type::string_type;
}
} i;
static struct f_type : public Type {
bool floatType(){
bool floatType()
{
return true;
}
bool canCastTo( Type *t ){
bool canCastTo(Type* t)
{
return t == Type::int_type || t == Type::float_type || t == Type::string_type;
}
} f;
static struct s_type : public Type {
bool stringType(){
bool stringType()
{
return true;
}
bool canCastTo( Type *t ){
bool canCastTo(Type* t)
{
return t == Type::int_type || t == Type::float_type || t == Type::string_type;
}
} s;
bool StructType::canCastTo( Type *t ){
bool StructType::canCastTo(Type* t)
{
return t == this || t == Type::null_type || (this == Type::null_type && t->structType());
}
bool VectorType::canCastTo( Type *t ){
if( this==t ) return true;
bool VectorType::canCastTo(Type* t)
{
if (this == t)
return true;
if (VectorType* v = t->vectorType()) {
if( elementType!=v->elementType ) return false;
if( sizes.size()!=v->sizes.size() ) return false;
if (elementType != v->elementType)
return false;
if (sizes.size() != v->sizes.size())
return false;
for (int k = 0; k < sizes.size(); ++k) {
if( sizes[k]!=v->sizes[k] ) return false;
if (sizes[k] != v->sizes[k])
return false;
}
return true;
}
+66 -17
View File
@@ -13,19 +13,46 @@ struct VectorType;
struct Type {
virtual ~Type() {}
virtual bool intType(){ return 0;}
virtual bool floatType(){ return 0; }
virtual bool stringType(){ return 0; }
virtual bool intType()
{
return 0;
}
virtual bool floatType()
{
return 0;
}
virtual bool stringType()
{
return 0;
}
//casts to inherited types
virtual FuncType *funcType(){ return 0; }
virtual ArrayType *arrayType(){ return 0; }
virtual StructType *structType(){ return 0; }
virtual ConstType *constType(){ return 0; }
virtual VectorType *vectorType(){ return 0; }
virtual FuncType* funcType()
{
return 0;
}
virtual ArrayType* arrayType()
{
return 0;
}
virtual StructType* structType()
{
return 0;
}
virtual ConstType* constType()
{
return 0;
}
virtual VectorType* vectorType()
{
return 0;
}
//operators
virtual bool canCastTo( Type *t ){ return this==t; }
virtual bool canCastTo(Type* t)
{
return this == t;
}
//built in types
static Type *void_type, *int_type, *float_type, *string_type, *null_type;
@@ -36,14 +63,24 @@ struct FuncType : public Type{
DeclSeq* params;
bool userlib, cfunc;
FuncType(Type* t, DeclSeq* p, bool ulib, bool cfn) : returnType(t), params(p), userlib(ulib), cfunc(cfn) {}
~FuncType(){ delete params; }
FuncType *funcType(){ return this; }
~FuncType()
{
delete params;
}
FuncType* funcType()
{
return this;
}
};
struct ArrayType : public Type {
Type *elementType;int dims;
Type* elementType;
int dims;
ArrayType(Type* t, int n) : elementType(t), dims(n) {}
ArrayType *arrayType(){ return this; }
ArrayType* arrayType()
{
return this;
}
};
struct StructType : public Type {
@@ -51,8 +88,14 @@ struct StructType : public Type{
DeclSeq* fields;
StructType(const string& i) : ident(i), fields(0) {}
StructType(const string& i, DeclSeq* f) : ident(i), fields(f) {}
~StructType(){ delete fields; }
StructType *structType(){ return this; }
~StructType()
{
delete fields;
}
StructType* structType()
{
return this;
}
virtual bool canCastTo(Type* t);
};
@@ -64,7 +107,10 @@ struct ConstType : public Type{
ConstType(int n) : intValue(n), valueType(Type::int_type) {}
ConstType(float n) : floatValue(n), valueType(Type::float_type) {}
ConstType(const string& n) : stringValue(n), valueType(Type::string_type) {}
ConstType *constType(){ return this; }
ConstType* constType()
{
return this;
}
};
struct VectorType : public Type {
@@ -72,7 +118,10 @@ struct VectorType : public Type{
Type* elementType;
vector<int> sizes;
VectorType(const string& l, Type* t, const vector<int>& szs) : label(l), elementType(t), sizes(szs) {}
VectorType *vectorType(){ return this; }
VectorType* vectorType()
{
return this;
}
virtual bool canCastTo(Type* t);
};
-1
View File
@@ -5,7 +5,6 @@
struct Type;
struct Var {
int index;
Type* type;
+66 -34
View File
@@ -1,39 +1,47 @@
#include "std.hpp"
#include "nodes.hpp"
#include "std.hpp"
//////////////////////////////////
// Common get/set for variables //
//////////////////////////////////
TNode *VarNode::load( Codegen *g ){
TNode* VarNode::load(Codegen* g)
{
TNode* t = translate(g);
if( sem_type==Type::string_type ) return call( "__bbStrLoad",t );
if (sem_type == Type::string_type)
return call("__bbStrLoad", t);
return mem(t);
}
TNode *VarNode::store( Codegen *g,TNode *n ){
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 );
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(){
bool VarNode::isObjParam()
{
return false;
}
//////////////////
// Declared var //
//////////////////
void DeclVarNode::semant( Environ *e ){
}
void DeclVarNode::semant(Environ* e) {}
TNode *DeclVarNode::translate( Codegen *g ){
if( sem_decl->kind==DECL_GLOBAL ) return global( "_v"+sem_decl->name );
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 ){
TNode* DeclVarNode::store(Codegen* g, TNode* n)
{
if (isObjParam()) {
TNode* t = translate(g);
return move(n, mem(t));
@@ -41,23 +49,30 @@ TNode *DeclVarNode::store( Codegen *g,TNode *n ){
return VarNode::store(g, n);
}
bool DeclVarNode::isObjParam(){
bool DeclVarNode::isObjParam()
{
return sem_type->structType() && sem_decl->kind == DECL_PARAM;
}
///////////////
// Ident var //
///////////////
void IdentVarNode::semant( Environ *e ){
if( sem_decl ) return;
Type *t=tagType( tag,e );if( !t ) t=Type::int_type;
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" );
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);
@@ -68,19 +83,24 @@ void IdentVarNode::semant( Environ *e ){
/////////////////
// Indexed Var //
/////////////////
void ArrayVarNode::semant( Environ *e ){
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" );
if (!sem_decl || !(sem_decl->kind & DECL_ARRAY))
ex("Array not found");
ArrayType* a = sem_decl->type->arrayType();
if( t && t!=a->elementType ) ex( "array type mismtach" );
if( a->dims!=exprs->size() ) ex( "incorrect number of dimensions" );
if (t && t != a->elementType)
ex("array type mismtach");
if (a->dims != exprs->size())
ex("incorrect number of dimensions");
sem_type = a->elementType;
}
TNode *ArrayVarNode::translate( Codegen *g ){
TNode* ArrayVarNode::translate(Codegen* g)
{
TNode* t = 0;
for (int k = 0; k < exprs->size(); ++k) {
TNode* e = exprs->exprs[k]->translate(g);
@@ -91,7 +111,8 @@ TNode *ArrayVarNode::translate( Codegen *g ){
if (g->debug) {
TNode* s = mem(add(global("_a" + ident), iconst(k * 4 + 12)));
t = jumpge(e, s, "__bbArrayBoundsEx");
}else t=e;
} else
t = e;
}
t = add(mem(global("_a" + ident)), mul(t, iconst(4)));
return t;
@@ -100,30 +121,40 @@ TNode *ArrayVarNode::translate( Codegen *g ){
///////////////
// Field var //
///////////////
void FieldVarNode::semant( Environ *e ){
void FieldVarNode::semant(Environ* e)
{
expr = expr->semant(e);
StructType* s = expr->sem_type->structType();
if( !s ) ex( "Variable must be a Type" );
if (!s)
ex("Variable must be a Type");
sem_field = s->fields->findDecl(ident);
if( !sem_field ) ex( "Type field not found" );
if (!sem_field)
ex("Type field not found");
sem_type = sem_field->type;
}
TNode *FieldVarNode::translate( Codegen *g ){
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" );
if (g->debug)
t = jumpf(t, "__bbNullObjEx");
t = mem(t);
if (g->debug)
t = jumpf(t, "__bbNullObjEx");
return add(t, iconst(sem_field->offset));
}
////////////////
// Vector var //
////////////////
void VectorVarNode::semant( Environ *e ){
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" );
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) {
@@ -136,7 +167,8 @@ void VectorVarNode::semant( Environ *e ){
sem_type = vec_type->elementType;
}
TNode *VectorVarNode::translate( Codegen *g ){
TNode* VectorVarNode::translate(Codegen* g)
{
int sz = 4;
TNode* t = 0;
for (int k = 0; k < exprs->size(); ++k) {
+18 -4
View File
@@ -21,7 +21,11 @@ struct VarNode : public Node{
struct DeclVarNode : public VarNode {
Decl* sem_decl;
DeclVarNode( Decl *d=0 ):sem_decl(d){ if( d ) sem_type=d->type; }
DeclVarNode(Decl* d = 0) : sem_decl(d)
{
if (d)
sem_type = d->type;
}
void semant(Environ* e);
TNode* translate(Codegen* g);
virtual TNode* store(Codegen* g, TNode* n);
@@ -39,7 +43,10 @@ struct ArrayVarNode : public VarNode{
ExprSeqNode* exprs;
Decl* sem_decl;
ArrayVarNode(const string& i, const string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {}
~ArrayVarNode(){ delete exprs; }
~ArrayVarNode()
{
delete exprs;
}
void semant(Environ* e);
TNode* translate(Codegen* g);
};
@@ -49,7 +56,10 @@ struct FieldVarNode : public VarNode{
string ident, tag;
Decl* sem_field;
FieldVarNode(ExprNode* e, const string& i, const string& t) : expr(e), ident(i), tag(t) {}
~FieldVarNode(){ delete expr; }
~FieldVarNode()
{
delete expr;
}
void semant(Environ* e);
TNode* translate(Codegen* g);
};
@@ -59,7 +69,11 @@ struct VectorVarNode : public VarNode{
ExprSeqNode* exprs;
VectorType* vec_type;
VectorVarNode(ExprNode* e, ExprSeqNode* es) : expr(e), exprs(es) {}
~VectorVarNode(){ delete expr;delete exprs; }
~VectorVarNode()
{
delete expr;
delete exprs;
}
void semant(Environ* e);
TNode* translate(Codegen* g);
};