Holy fucking shit I don't want to work on this. Sibly, you son of a ...
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@
|
||||
#ifndef ASSEM_H
|
||||
#define ASSEM_H
|
||||
|
||||
#include "..\linker\linker.h"
|
||||
#include "..\LinkerLib\linker.h"
|
||||
|
||||
class Assem{
|
||||
public:
|
||||
|
||||
+585
-585
File diff suppressed because it is too large
Load Diff
+159
-158
@@ -4,270 +4,271 @@
|
||||
#include "tile.h"
|
||||
|
||||
//reduce to 3 for stress test
|
||||
static const int NUM_REGS=6;
|
||||
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];
|
||||
static bool regUsed[NUM_REGS + 1];
|
||||
|
||||
//size of locals in function
|
||||
static int frameSize,maxFrameSize;
|
||||
static int frameSize, maxFrameSize;
|
||||
|
||||
//code fragments
|
||||
static vector<string> codeFrags,dataFrags;
|
||||
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 ){
|
||||
if( !n || regUsed[n] ){
|
||||
for( n=NUM_REGS;n>=1 && regUsed[n];--n ){}
|
||||
if( !n ) return 0;
|
||||
static int allocReg(int n) {
|
||||
if (!n || regUsed[n]) {
|
||||
for (n = NUM_REGS; n >= 1 && regUsed[n]; --n) {}
|
||||
if (!n) return 0;
|
||||
}
|
||||
regUsed[n]=true;
|
||||
regUsed[n] = true;
|
||||
return n;
|
||||
}
|
||||
|
||||
static void freeReg( int n ){
|
||||
regUsed[n]=false;
|
||||
static void freeReg(int n) {
|
||||
regUsed[n] = false;
|
||||
}
|
||||
|
||||
static void pushReg( int n ){
|
||||
frameSize+=4;
|
||||
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';
|
||||
codeFrags.push_back( s );
|
||||
static void pushReg(int n) {
|
||||
frameSize += 4;
|
||||
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';
|
||||
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";
|
||||
codeFrags.push_back( s );
|
||||
frameSize-=4;
|
||||
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 ){
|
||||
string t="\tmov\t"+regs[d]+','+regs[s]+'\n';
|
||||
codeFrags.push_back( t );
|
||||
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 ){
|
||||
string t="\txchg\t"+regs[d]+','+regs[s]+'\n';
|
||||
codeFrags.push_back( t );
|
||||
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){
|
||||
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) {
|
||||
}
|
||||
|
||||
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){
|
||||
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) {
|
||||
}
|
||||
|
||||
Tile::~Tile(){
|
||||
delete l;delete r;
|
||||
Tile::~Tile() {
|
||||
delete l; delete r;
|
||||
}
|
||||
|
||||
void Tile::label(){
|
||||
if( !l ){
|
||||
need=1;
|
||||
}else if( !r ){
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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( spill ){
|
||||
for( int n=1;n<=NUM_REGS;++n ){
|
||||
if( spill&(1<<n) ){
|
||||
if( regUsed[n] ) pushReg( n );
|
||||
else spill&=~(1<<n);
|
||||
int spill = hits;
|
||||
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 tile needs an argFrame...
|
||||
if( argFrame ){
|
||||
codeFrags.push_back( "-"+itoa(argFrame) );
|
||||
if (argFrame) {
|
||||
codeFrags.push_back("-" + itoa(argFrame));
|
||||
}
|
||||
|
||||
int got_l=0,got_r=0;
|
||||
if( want_l ) want=want_l;
|
||||
int got_l = 0, got_r = 0;
|
||||
if (want_l) want = want_l;
|
||||
|
||||
string *as=&assem;
|
||||
string *as = &assem;
|
||||
|
||||
if( !l ){
|
||||
got_l=allocReg( want );
|
||||
}else if( !r ){
|
||||
got_l=l->eval( want );
|
||||
}else{
|
||||
if( l->need>=NUM_REGS && r->need>=NUM_REGS ){
|
||||
got_r=r->eval( 0 );
|
||||
pushReg( got_r );freeReg( got_r );
|
||||
got_l=l->eval( want );
|
||||
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 (!l) {
|
||||
got_l = allocReg(want);
|
||||
} else if (!r) {
|
||||
got_l = l->eval(want);
|
||||
} else {
|
||||
if (l->need >= NUM_REGS && r->need >= NUM_REGS) {
|
||||
got_r = r->eval(0);
|
||||
pushReg(got_r); freeReg(got_r);
|
||||
got_l = l->eval(want);
|
||||
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( want_l==got_r || want_r==got_l ){
|
||||
swapRegs( got_l,got_r );
|
||||
int t=got_l;got_l=got_r;got_r=t;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
codeFrags.push_back(*as);
|
||||
|
||||
freeReg( got_r );
|
||||
if( want_l!=got_l ) moveReg( got_l,want_l );
|
||||
freeReg(got_r);
|
||||
if (want_l != got_l) moveReg(got_l, want_l);
|
||||
|
||||
//cleanup argFrame
|
||||
if( argFrame ){
|
||||
if (argFrame) {
|
||||
//***** Not needed for STDCALL *****
|
||||
// codeFrags.push_back( "+"+itoa(argFrame) );
|
||||
}
|
||||
|
||||
//restore spilled regs
|
||||
if( spill ){
|
||||
for( int n=NUM_REGS;n>=1;--n ){
|
||||
if( spill&(1<<n) ) popReg( n );
|
||||
if (spill) {
|
||||
for (int n = NUM_REGS; n >= 1; --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;
|
||||
inCode = true;
|
||||
::frameSize = maxFrameSize = frameSize;
|
||||
codeFrags.clear(); funcLabel = l;
|
||||
}
|
||||
|
||||
void Codegen_x86::code( TNode *stmt ){
|
||||
void Codegen_x86::code(TNode *stmt) {
|
||||
resetRegs();
|
||||
Tile *q=munch( stmt );
|
||||
Tile *q = munch(stmt);
|
||||
q->label();
|
||||
q->eval( 0 );
|
||||
q->eval(0);
|
||||
delete q;
|
||||
delete stmt;
|
||||
}
|
||||
|
||||
static string fixEsp( int esp_off ){
|
||||
if( esp_off<0 ) return "\tsub\tesp,"+itoa(-esp_off)+"\n";
|
||||
return "\tadd\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 ){
|
||||
if( cleanup ){
|
||||
void Codegen_x86::leave(TNode *cleanup, int pop_sz) {
|
||||
if (cleanup) {
|
||||
resetRegs();
|
||||
allocReg( EAX );
|
||||
Tile *q=munch( cleanup );
|
||||
allocReg(EAX);
|
||||
Tile *q = munch(cleanup);
|
||||
q->label();
|
||||
q->eval( 0 );
|
||||
q->eval(0);
|
||||
delete q;
|
||||
}
|
||||
|
||||
out<<"\t.align\t16\n";
|
||||
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';
|
||||
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';
|
||||
|
||||
int esp_off=0;
|
||||
vector<string>::iterator it=codeFrags.begin();
|
||||
for( it=codeFrags.begin();it!=codeFrags.end();++it ){
|
||||
const string &t=*it;
|
||||
if( t[0]=='+' ){
|
||||
esp_off+=atoi(t.substr(1));
|
||||
}else if( t[0]=='-' ){
|
||||
int esp_off = 0;
|
||||
vector<string>::iterator it = codeFrags.begin();
|
||||
for (it = codeFrags.begin(); it != codeFrags.end(); ++it) {
|
||||
const string &t = *it;
|
||||
if (t[0] == '+') {
|
||||
esp_off += atoi(t.substr(1));
|
||||
} else if (t[0] == '-') {
|
||||
//***** Still needed for STDCALL *****
|
||||
esp_off-=atoi(t.substr(1));
|
||||
}else{
|
||||
if( esp_off ){
|
||||
out<<fixEsp( esp_off );
|
||||
esp_off=0;
|
||||
esp_off -= atoi(t.substr(1));
|
||||
} else {
|
||||
if (esp_off) {
|
||||
out << fixEsp(esp_off);
|
||||
esp_off = 0;
|
||||
}
|
||||
out<<*it;
|
||||
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";
|
||||
out<<"\tpop\tedi\n";
|
||||
out<<"\tpop\tesi\n";
|
||||
out<<"\tpop\tebx\n";
|
||||
out<<"\tret\tword "<<pop_sz<<"\n";
|
||||
out << "\tmov\tesp,ebp\n";
|
||||
out << "\tpop\tebp\n";
|
||||
out << "\tpop\tedi\n";
|
||||
out << "\tpop\tesi\n";
|
||||
out << "\tpop\tebx\n";
|
||||
out << "\tret\tword " << pop_sz << "\n";
|
||||
|
||||
delete cleanup;
|
||||
inCode=false;
|
||||
inCode = false;
|
||||
}
|
||||
|
||||
void Codegen_x86::label( const string &l ){
|
||||
string t=l+'\n';
|
||||
if( inCode ) codeFrags.push_back( t );
|
||||
else dataFrags.push_back( t );
|
||||
void Codegen_x86::label(const string &l) {
|
||||
string t = l + '\n';
|
||||
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 );
|
||||
dataFrags.push_back( string( "\t.align\t" )+buff+'\n' );
|
||||
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 );
|
||||
dataFrags.push_back( string( "\t.dd\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);
|
||||
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 );
|
||||
dataFrags.push_back( string( "\t.db\t\"" )+s+"\",0\n" );
|
||||
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 );
|
||||
dataFrags.push_back( string( "\t.dd\t" )+p+'\n' );
|
||||
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');
|
||||
}
|
||||
|
||||
+41
-155
@@ -1,14 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Blitz2DRelease|Win32">
|
||||
<Configuration>Blitz2DRelease</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Blitz3DRelease|Win32">
|
||||
<Configuration>Blitz3DRelease</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
@@ -17,22 +9,15 @@
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Template|Win32">
|
||||
<Configuration>Template</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<SccProjectName />
|
||||
<SccLocalPath />
|
||||
<ProjectGuid>{D884A075-E3B8-44E1-838D-74F28B33391B}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>Compiler</ProjectName>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
@@ -45,24 +30,9 @@
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
@@ -71,112 +41,46 @@
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">
|
||||
<OutDir>.\compiler___Win32_Blitz2DRelease\</OutDir>
|
||||
<IntDir>.\compiler___Win32_Blitz2DRelease\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">
|
||||
<OutDir>.\compiler___Win32_Blitz3DRelease\</OutDir>
|
||||
<IntDir>.\compiler___Win32_Blitz3DRelease\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>..\#Build\$(ProjectName)\$(ConfigurationName)\</OutDir>
|
||||
<IntDir>..\#Intermediate\$(ProjectName)\$(ConfigurationName)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(DXSDK_DIR)Include\;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
||||
<LibraryPath>$(DXSDK_DIR)Lib\x86\;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>.\Release\</OutDir>
|
||||
<IntDir>.\Release\</IntDir>
|
||||
<OutDir>..\#Build\$(ProjectName)\$(ConfigurationName)\</OutDir>
|
||||
<IntDir>..\#Intermediate\$(ProjectName)\$(ConfigurationName)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(DXSDK_DIR)Include\;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
||||
<LibraryPath>$(DXSDK_DIR)Lib\x86\;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<StringPooling>true</StringPooling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AssemblerListingLocation>.\compiler___Win32_Blitz2DRelease\</AssemblerListingLocation>
|
||||
<PrecompiledHeaderOutputFile>.\compiler___Win32_Blitz2DRelease\compiler.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>std.h</PrecompiledHeaderFile>
|
||||
<ObjectFileName>.\compiler___Win32_Blitz2DRelease\</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\compiler___Win32_Blitz2DRelease\</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\compiler___Win32_Blitz2DRelease\compiler.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<Lib>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\compiler___Win32_Blitz2DRelease\compiler.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<StringPooling>true</StringPooling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>_LIB;WIN32;NDEBUG;PRO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AssemblerListingLocation>.\compiler___Win32_Blitz3DRelease\</AssemblerListingLocation>
|
||||
<PrecompiledHeaderOutputFile>.\compiler___Win32_Blitz3DRelease\compiler.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeader />
|
||||
<ObjectFileName>.\compiler___Win32_Blitz3DRelease\</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\compiler___Win32_Blitz3DRelease\</ProgramDataBaseFileName>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\compiler___Win32_Blitz3DRelease\compiler.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<Lib>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\compiler___Win32_Blitz3DRelease\compiler.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AssemblerListingLocation>.\Debug\</AssemblerListingLocation>
|
||||
<PrecompiledHeaderOutputFile>.\Debug\compiler.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>std.h</PrecompiledHeaderFile>
|
||||
<ObjectFileName>.\Debug\</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<StringPooling>true</StringPooling>
|
||||
<FloatingPointExceptions>true</FloatingPointExceptions>
|
||||
<CreateHotpatchableImage>true</CreateHotpatchableImage>
|
||||
<CompileAsManaged>false</CompileAsManaged>
|
||||
<CompileAsWinRT>false</CompileAsWinRT>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<OpenMPSupport>false</OpenMPSupport>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
@@ -188,25 +92,32 @@
|
||||
</Bscmake>
|
||||
<Lib>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Debug\compiler.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<StringPooling>true</StringPooling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AssemblerListingLocation>.\Release\</AssemblerListingLocation>
|
||||
<PrecompiledHeaderOutputFile>.\Release\compiler.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>std.h</PrecompiledHeaderFile>
|
||||
<ObjectFileName>.\Release\</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<FloatingPointExceptions>true</FloatingPointExceptions>
|
||||
<CreateHotpatchableImage>true</CreateHotpatchableImage>
|
||||
<CompileAsManaged>false</CompileAsManaged>
|
||||
<CompileAsWinRT>false</CompileAsWinRT>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnforceTypeConversionRules>false</EnforceTypeConversionRules>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<OpenMPSupport>false</OpenMPSupport>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
@@ -218,55 +129,34 @@
|
||||
</Bscmake>
|
||||
<Lib>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Release\compiler.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="assem_x86\asm_insts.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="assem_x86\assem_x86.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="assem_x86\operand.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="codegen_x86\codegen_x86.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="codegen_x86\tile.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
@@ -280,10 +170,6 @@
|
||||
<ClCompile Include="parser.cpp" />
|
||||
<ClCompile Include="prognode.cpp" />
|
||||
<ClCompile Include="std.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz2DRelease|Win32'">std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Blitz3DRelease|Win32'">std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">std.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
|
||||
+168
-163
@@ -5,46 +5,42 @@
|
||||
//////////////////////////////
|
||||
// Sequence of declarations //
|
||||
//////////////////////////////
|
||||
void DeclSeqNode::proto( DeclSeq *d,Environ *e ){
|
||||
for( int 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;
|
||||
throw;
|
||||
void DeclSeqNode::proto(DeclSeq *d, Environ *e) {
|
||||
for (int 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;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeclSeqNode::semant( Environ *e ){
|
||||
for( int 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;
|
||||
throw;
|
||||
void DeclSeqNode::semant(Environ *e) {
|
||||
for (int 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;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeclSeqNode::translate( Codegen *g ){
|
||||
for( int 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;
|
||||
throw;
|
||||
void DeclSeqNode::translate(Codegen *g) {
|
||||
for (int 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;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeclSeqNode::transdata( Codegen *g ){
|
||||
for( int 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;
|
||||
throw;
|
||||
void DeclSeqNode::transdata(Codegen *g) {
|
||||
for (int 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;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,154 +48,163 @@ 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;
|
||||
ConstType *defType=0;
|
||||
Type *ty = tagType(tag, e);
|
||||
if (!ty) ty = Type::int_type;
|
||||
ConstType *defType = 0;
|
||||
|
||||
if( expr ){
|
||||
expr=expr->semant( e );
|
||||
expr=expr->castTo( ty,e );
|
||||
if( constant || (kind&DECL_PARAM) ){
|
||||
ConstNode *c=expr->constNode();
|
||||
if( !c ) ex( "Expression must be constant" );
|
||||
if( ty==Type::int_type ) ty=d_new ConstType( c->intValue() );
|
||||
else if( ty==Type::float_type ) ty=d_new ConstType( c->floatValue() );
|
||||
else ty=d_new ConstType( c->stringValue() );
|
||||
e->types.push_back( ty );
|
||||
delete expr;expr=0;
|
||||
if (expr != nullptr) {
|
||||
expr->semant(e);
|
||||
if (expr == nullptr) {
|
||||
ex("Internal Error: expr turned into nullptr (1)");
|
||||
}
|
||||
if( kind&DECL_PARAM ){
|
||||
defType=ty->constType();ty=defType->valueType;
|
||||
expr = expr->castTo(ty, e);
|
||||
if (expr == nullptr) {
|
||||
ex("Internal Error: expr turned into nullptr (2)");
|
||||
}
|
||||
}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=d_new DeclVarNode( decl );
|
||||
if (constant || (kind&DECL_PARAM)) {
|
||||
ConstNode *c = expr->constNode();
|
||||
|
||||
|
||||
if (!c) ex("Expression must be constant");
|
||||
if (ty == Type::int_type) ty = d_new ConstType(c->intValue());
|
||||
else if (ty == Type::float_type) ty = d_new ConstType(c->floatValue());
|
||||
else ty = d_new ConstType(c->stringValue());
|
||||
e->types.push_back(ty);
|
||||
delete expr; expr = 0;
|
||||
}
|
||||
if (kind&DECL_PARAM) {
|
||||
defType = ty->constType(); ty = defType->valueType;
|
||||
}
|
||||
} 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 = d_new DeclVarNode(decl);
|
||||
}
|
||||
|
||||
void VarDeclNode::semant( Environ *e ){
|
||||
void VarDeclNode::semant(Environ *e) {
|
||||
}
|
||||
|
||||
void VarDeclNode::translate( Codegen *g ){
|
||||
if( kind & DECL_GLOBAL ){
|
||||
g->align_data( 4 );
|
||||
g->i_data( 0,"_v"+ident );
|
||||
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;
|
||||
a_ptr<DeclSeq> decls( d_new DeclSeq() );
|
||||
params->proto( decls,e );
|
||||
sem_type=d_new FuncType( t,decls.release(),false,false );
|
||||
if( !d->insertDecl( ident,sem_type,DECL_FUNC ) ){
|
||||
delete sem_type;ex( "duplicate identifier" );
|
||||
void FuncDeclNode::proto(DeclSeq *d, Environ *e) {
|
||||
Type *t = tagType(tag, e); if (!t) t = Type::int_type;
|
||||
a_ptr<DeclSeq> decls(d_new DeclSeq());
|
||||
params->proto(decls, e);
|
||||
sem_type = d_new FuncType(t, decls.release(), false, false);
|
||||
if (!d->insertDecl(ident, sem_type, DECL_FUNC)) {
|
||||
delete sem_type; ex("duplicate identifier");
|
||||
}
|
||||
e->types.push_back( sem_type );
|
||||
e->types.push_back(sem_type);
|
||||
}
|
||||
|
||||
void FuncDeclNode::semant( Environ *e ){
|
||||
void FuncDeclNode::semant(Environ *e) {
|
||||
|
||||
sem_env=d_new Environ( genLabel(),sem_type->returnType,1,e );
|
||||
DeclSeq *decls=sem_env->decls;
|
||||
sem_env = d_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" );
|
||||
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");
|
||||
}
|
||||
|
||||
stmts->semant( sem_env );
|
||||
stmts->semant(sem_env);
|
||||
}
|
||||
|
||||
void FuncDeclNode::translate( Codegen *g ){
|
||||
void FuncDeclNode::translate(Codegen *g) {
|
||||
|
||||
//var offsets
|
||||
int size=enumVars( sem_env );
|
||||
int size = enumVars(sem_env);
|
||||
|
||||
//enter function
|
||||
g->enter( "_f"+ident,size );
|
||||
g->enter("_f" + ident, size);
|
||||
|
||||
//initialize locals
|
||||
TNode *t=createVars( sem_env );
|
||||
if( t ) g->code( t );
|
||||
if( g->debug ){
|
||||
string t=genLabel();
|
||||
g->s_data( ident,t );
|
||||
g->code( call( "__bbDebugEnter",local(0),iconst((int)sem_env),global(t) ) );
|
||||
TNode *t = createVars(sem_env);
|
||||
if (t) g->code(t);
|
||||
if (g->debug) {
|
||||
string t = genLabel();
|
||||
g->s_data(ident, t);
|
||||
g->code(call("__bbDebugEnter", local(0), iconst((int)sem_env), global(t)));
|
||||
}
|
||||
|
||||
//translate statements
|
||||
stmts->translate( g );
|
||||
stmts->translate(g);
|
||||
|
||||
for( int k=0;k<sem_env->labels.size();++k ){
|
||||
if( sem_env->labels[k]->def<0 ) ex( "Undefined label",sem_env->labels[k]->ref );
|
||||
for (int k = 0; k < sem_env->labels.size(); ++k) {
|
||||
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=d_new TNode( IR_SEQ,call( "__bbDebugLeave" ),t );
|
||||
g->leave( t,sem_type->params->size()*4 );
|
||||
g->label(sem_env->funcLabel + "_leave");
|
||||
t = deleteVars(sem_env);
|
||||
if (g->debug) t = d_new TNode(IR_SEQ, call("__bbDebugLeave"), t);
|
||||
g->leave(t, sem_type->params->size() * 4);
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// Type Declaration //
|
||||
//////////////////////
|
||||
void StructDeclNode::proto( DeclSeq *d,Environ *e ){
|
||||
sem_type=d_new StructType( ident,d_new DeclSeq() );
|
||||
if( !d->insertDecl( ident,sem_type,DECL_STRUCT ) ){
|
||||
delete sem_type;ex( "Duplicate identifier" );
|
||||
void StructDeclNode::proto(DeclSeq *d, Environ *e) {
|
||||
sem_type = d_new StructType(ident, d_new DeclSeq());
|
||||
if (!d->insertDecl(ident, sem_type, DECL_STRUCT)) {
|
||||
delete sem_type; ex("Duplicate identifier");
|
||||
}
|
||||
e->types.push_back( sem_type );
|
||||
e->types.push_back(sem_type);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
void StructDeclNode::translate( Codegen *g ){
|
||||
void StructDeclNode::translate(Codegen *g) {
|
||||
|
||||
//translate fields
|
||||
fields->translate( g );
|
||||
fields->translate(g);
|
||||
|
||||
//type ID
|
||||
g->align_data( 4 );
|
||||
g->i_data( 5,"_t"+ident );
|
||||
g->align_data(4);
|
||||
g->i_data(5, "_t" + ident);
|
||||
|
||||
//used and free lists for type
|
||||
int k;
|
||||
for( k=0;k<2;++k ){
|
||||
string lab=genLabel();
|
||||
g->i_data( 0,lab ); //fields
|
||||
g->p_data( lab ); //next
|
||||
g->p_data( lab ); //prev
|
||||
g->i_data( 0 ); //type
|
||||
g->i_data( -1 ); //ref_cnt
|
||||
for (k = 0; k < 2; ++k) {
|
||||
string lab = genLabel();
|
||||
g->i_data(0, lab); //fields
|
||||
g->p_data(lab); //next
|
||||
g->p_data(lab); //prev
|
||||
g->i_data(0); //type
|
||||
g->i_data(-1); //ref_cnt
|
||||
}
|
||||
|
||||
//number of fields
|
||||
g->i_data( sem_type->fields->size() );
|
||||
g->i_data(sem_type->fields->size());
|
||||
|
||||
//type of each field
|
||||
for( k=0;k<sem_type->fields->size();++k ){
|
||||
Decl *field=sem_type->fields->decls[k];
|
||||
Type *type=field->type;
|
||||
for (k = 0; k < sem_type->fields->size(); ++k) {
|
||||
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;
|
||||
g->p_data( 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;
|
||||
g->p_data(t);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -207,74 +212,74 @@ void StructDeclNode::translate( Codegen *g ){
|
||||
//////////////////////
|
||||
// Data declaration //
|
||||
//////////////////////
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
void DataDeclNode::semant( Environ *e ){
|
||||
void DataDeclNode::semant(Environ *e) {
|
||||
}
|
||||
|
||||
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::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 ){
|
||||
ConstNode *c=expr->constNode();
|
||||
if( expr->sem_type==Type::int_type ){
|
||||
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 );
|
||||
}else{
|
||||
g->i_data( 4 );g->p_data( str_label );
|
||||
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());
|
||||
} else if (expr->sem_type == Type::float_type) {
|
||||
float n = c->floatValue();
|
||||
g->i_data(2); g->i_data(*(int*)&n);
|
||||
} else {
|
||||
g->i_data(4); g->p_data(str_label);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
// Vector declaration //
|
||||
////////////////////////
|
||||
void VectorDeclNode::proto( DeclSeq *d,Environ *env ){
|
||||
void VectorDeclNode::proto(DeclSeq *d, Environ *env) {
|
||||
|
||||
Type *ty=tagType( tag,env );if( !ty ) ty=Type::int_type;
|
||||
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" );
|
||||
int n=c->intValue();
|
||||
if( n<0 ) ex( "Blitz array sizes must not be negative" );
|
||||
sizes.push_back( n+1 );
|
||||
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");
|
||||
int n = c->intValue();
|
||||
if (n < 0) ex("Blitz array sizes must not be negative");
|
||||
sizes.push_back(n + 1);
|
||||
}
|
||||
string label=genLabel();
|
||||
sem_type=d_new VectorType( label,ty,sizes );
|
||||
if( !d->insertDecl( ident,sem_type,kind ) ){
|
||||
delete sem_type;ex( "Duplicate identifier" );
|
||||
string label = genLabel();
|
||||
sem_type = d_new VectorType(label, ty, sizes);
|
||||
if (!d->insertDecl(ident, sem_type, kind)) {
|
||||
delete sem_type; ex("Duplicate identifier");
|
||||
}
|
||||
env->types.push_back( sem_type );
|
||||
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( int k=0;k<v->sizes.size();++k ) sz*=v->sizes[k];
|
||||
g->i_data( sz );
|
||||
g->align_data(4);
|
||||
VectorType *v = sem_type->vectorType();
|
||||
g->i_data(6, v->label);
|
||||
int sz = 1;
|
||||
for (int 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;
|
||||
g->p_data( 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;
|
||||
g->p_data(t);
|
||||
|
||||
if( kind==DECL_GLOBAL ) g->i_data( 0,"_v"+ident );
|
||||
if (kind == DECL_GLOBAL) g->i_data(0, "_v" + ident);
|
||||
}
|
||||
|
||||
+348
-347
@@ -8,65 +8,66 @@
|
||||
//////////////////////////////////
|
||||
// Cast an expression to a type //
|
||||
//////////////////////////////////
|
||||
ExprNode *ExprNode::castTo( Type *ty,Environ *e ){
|
||||
if( !sem_type->canCastTo( ty ) ){
|
||||
ex( "Illegal type conversion" );
|
||||
ExprNode *ExprNode::castTo(Type *ty, Environ *e) {
|
||||
if (!sem_type->canCastTo(ty)) {
|
||||
ex("Illegal type conversion");
|
||||
}
|
||||
|
||||
ExprNode *cast=d_new CastNode( this,ty );
|
||||
return cast->semant( e );
|
||||
ExprNode *cast = d_new CastNode(this, ty);
|
||||
cast->semant(e);
|
||||
return cast;
|
||||
}
|
||||
|
||||
ExprNode *CastNode::semant( Environ *e ){
|
||||
if( !expr->sem_type ){
|
||||
expr=expr->semant( e );
|
||||
ExprNode *CastNode::semant(Environ *e) {
|
||||
if (!expr->sem_type) {
|
||||
expr = expr->semant(e);
|
||||
}
|
||||
|
||||
if( ConstNode *c=expr->constNode() ){
|
||||
if (ConstNode *c = expr->constNode()) {
|
||||
ExprNode *e;
|
||||
if( type==Type::int_type ) e=d_new IntConstNode( c->intValue() );
|
||||
else if( type==Type::float_type ) e=d_new FloatConstNode( c->floatValue() );
|
||||
else e=d_new StringConstNode( c->stringValue() );
|
||||
if (type == Type::int_type) e = d_new IntConstNode(c->intValue());
|
||||
else if (type == Type::float_type) e = d_new FloatConstNode(c->floatValue());
|
||||
else e = d_new StringConstNode(c->stringValue());
|
||||
delete this;
|
||||
return e;
|
||||
}
|
||||
|
||||
sem_type=type;
|
||||
sem_type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
// Cast an expression to a type //
|
||||
//////////////////////////////////
|
||||
TNode *CastNode::translate( Codegen *g ){
|
||||
TNode *t=expr->translate( g );
|
||||
if( expr->sem_type==Type::float_type && sem_type==Type::int_type ){
|
||||
TNode *CastNode::translate(Codegen *g) {
|
||||
TNode *t = expr->translate(g);
|
||||
if (expr->sem_type == Type::float_type && sem_type == Type::int_type) {
|
||||
//float->int
|
||||
return d_new TNode( IR_CAST,t,0 );
|
||||
return d_new TNode(IR_CAST, t, 0);
|
||||
}
|
||||
if( expr->sem_type==Type::int_type && sem_type==Type::float_type ){
|
||||
if (expr->sem_type == Type::int_type && sem_type == Type::float_type) {
|
||||
//int->float
|
||||
return d_new TNode( IR_FCAST,t,0 );
|
||||
return d_new TNode(IR_FCAST, t, 0);
|
||||
}
|
||||
if( expr->sem_type==Type::string_type && sem_type==Type::int_type ){
|
||||
if (expr->sem_type == Type::string_type && sem_type == Type::int_type) {
|
||||
//str->int
|
||||
return call( "__bbStrToInt",t );
|
||||
return call("__bbStrToInt", t);
|
||||
}
|
||||
if( expr->sem_type==Type::int_type && sem_type==Type::string_type ){
|
||||
if (expr->sem_type == Type::int_type && sem_type == Type::string_type) {
|
||||
//int->str
|
||||
return call( "__bbStrFromInt",t );
|
||||
return call("__bbStrFromInt", t);
|
||||
}
|
||||
if( expr->sem_type==Type::string_type && sem_type==Type::float_type ){
|
||||
if (expr->sem_type == Type::string_type && sem_type == Type::float_type) {
|
||||
//str->float
|
||||
return fcall( "__bbStrToFloat",t );
|
||||
return fcall("__bbStrToFloat", t);
|
||||
}
|
||||
if( expr->sem_type==Type::float_type && sem_type==Type::string_type ){
|
||||
if (expr->sem_type == Type::float_type && sem_type == Type::string_type) {
|
||||
//float->str
|
||||
return call( "__bbStrFromFloat",t );
|
||||
return call("__bbStrFromFloat", t);
|
||||
}
|
||||
if( expr->sem_type->structType() && sem_type==Type::string_type ){
|
||||
if (expr->sem_type->structType() && sem_type == Type::string_type) {
|
||||
//obj->str
|
||||
return call( "__bbObjToStr",t );
|
||||
return call("__bbObjToStr", t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
@@ -74,111 +75,111 @@ TNode *CastNode::translate( Codegen *g ){
|
||||
/////////////////////////////
|
||||
// Sequence of Expressions //
|
||||
/////////////////////////////
|
||||
void ExprSeqNode::semant( Environ *e ){
|
||||
for( int k=0;k<exprs.size();++k ){
|
||||
if( exprs[k] ) exprs[k]=exprs[k]->semant( e );
|
||||
void ExprSeqNode::semant(Environ *e) {
|
||||
for (int k = 0; k < exprs.size(); ++k) {
|
||||
if (exprs[k]) exprs[k] = exprs[k]->semant(e);
|
||||
}
|
||||
}
|
||||
|
||||
TNode *ExprSeqNode::translate( Codegen *g,bool cfunc ){
|
||||
TNode *t=0,*l=0;
|
||||
for( int k=0;k<exprs.size();++k ){
|
||||
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);
|
||||
TNode *q = exprs[k]->translate(g);
|
||||
|
||||
if( cfunc ){
|
||||
Type *ty=exprs[k]->sem_type;
|
||||
if( ty->stringType() ){
|
||||
q=call( "__bbStrToCStr",q );
|
||||
}else if( ty->structType() ){
|
||||
q=d_new TNode( IR_MEM,q );
|
||||
}else if( ty==Type::void_type ){
|
||||
q=d_new TNode( IR_MEM,add(q,iconst(4)) );
|
||||
if (cfunc) {
|
||||
Type *ty = exprs[k]->sem_type;
|
||||
if (ty->stringType()) {
|
||||
q = call("__bbStrToCStr", q);
|
||||
} else if (ty->structType()) {
|
||||
q = d_new TNode(IR_MEM, q);
|
||||
} else if (ty == Type::void_type) {
|
||||
q = d_new TNode(IR_MEM, add(q, iconst(4)));
|
||||
}
|
||||
}
|
||||
|
||||
TNode *p;
|
||||
p=d_new TNode( IR_ARG,0,0,k*4 );
|
||||
p=d_new TNode( IR_MEM,p,0 );
|
||||
p=d_new TNode( IR_MOVE,q,p );
|
||||
p=d_new TNode( IR_SEQ,p,0 );
|
||||
if( l ) l->r=p;
|
||||
else t=p;
|
||||
l=p;
|
||||
p = d_new TNode(IR_ARG, 0, 0, k * 4);
|
||||
p = d_new TNode(IR_MEM, p, 0);
|
||||
p = d_new TNode(IR_MOVE, q, p);
|
||||
p = d_new TNode(IR_SEQ, p, 0);
|
||||
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" );
|
||||
for( int k=0;k<decls->size();++k ){
|
||||
Decl *d=decls->decls[k];
|
||||
if( k<exprs.size() && exprs[k] ){
|
||||
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() ){
|
||||
exprs[k]->sem_type=Type::void_type;
|
||||
}else{
|
||||
ex( "Illegal type conversion" );
|
||||
if (cfunc && d->type->structType()) {
|
||||
if (exprs[k]->sem_type->structType()) {
|
||||
} else if (exprs[k]->sem_type->intType()) {
|
||||
exprs[k]->sem_type = Type::void_type;
|
||||
} else {
|
||||
ex("Illegal type conversion");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
exprs[k]=exprs[k]->castTo( d->type,e );
|
||||
exprs[k] = exprs[k]->castTo(d->type, e);
|
||||
|
||||
}else{
|
||||
if( !d->defType ) ex( "Not enough parameters" );
|
||||
ExprNode *expr=constValue( d->defType );
|
||||
if( k<exprs.size() ) exprs[k]=expr;
|
||||
else exprs.push_back( expr );
|
||||
} else {
|
||||
if (!d->defType) ex("Not enough parameters");
|
||||
ExprNode *expr = constValue(d->defType);
|
||||
if (k < exprs.size()) exprs[k] = expr;
|
||||
else exprs.push_back(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExprSeqNode::castTo( Type *t,Environ *e ){
|
||||
for( int k=0;k<exprs.size();++k ){
|
||||
exprs[k]=exprs[k]->castTo( t,e );
|
||||
void ExprSeqNode::castTo(Type *t, Environ *e) {
|
||||
for (int k = 0; k < exprs.size(); ++k) {
|
||||
exprs[k] = exprs[k]->castTo(t, e);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// Function call //
|
||||
///////////////////
|
||||
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" );
|
||||
FuncType *f=sem_decl->type->funcType();
|
||||
if( t && f->returnType!=t ) ex( "incorrect function return type" );
|
||||
exprs->semant( e );
|
||||
exprs->castTo( f->params,e,f->cfunc );
|
||||
sem_type=f->returnType;
|
||||
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");
|
||||
FuncType *f = sem_decl->type->funcType();
|
||||
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();
|
||||
FuncType *f = sem_decl->type->funcType();
|
||||
|
||||
TNode *t;
|
||||
TNode *l=global( "_f"+ident );
|
||||
TNode *r=exprs->translate( g,f->cfunc );
|
||||
TNode *l = global("_f" + ident);
|
||||
TNode *r = exprs->translate(g, f->cfunc);
|
||||
|
||||
if( f->userlib ){
|
||||
l=d_new TNode( IR_MEM,l );
|
||||
usedfuncs.insert( ident );
|
||||
if (f->userlib) {
|
||||
l = d_new TNode(IR_MEM, l);
|
||||
usedfuncs.insert(ident);
|
||||
}
|
||||
|
||||
if( sem_type==Type::float_type ){
|
||||
t=d_new TNode( IR_FCALL,l,r,exprs->size()*4 );
|
||||
}else{
|
||||
t=d_new TNode( IR_CALL,l,r,exprs->size()*4 );
|
||||
if (sem_type == Type::float_type) {
|
||||
t = d_new TNode(IR_FCALL, l, r, exprs->size() * 4);
|
||||
} else {
|
||||
t = d_new TNode(IR_CALL, l, r, exprs->size() * 4);
|
||||
}
|
||||
|
||||
if( f->returnType->stringType() ){
|
||||
if( f->cfunc ){
|
||||
t=call( "__bbCStrToStr",t );
|
||||
if (f->returnType->stringType()) {
|
||||
if (f->cfunc) {
|
||||
t = call("__bbCStrToStr", t);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
@@ -187,232 +188,232 @@ TNode *CallNode::translate( Codegen *g ){
|
||||
/////////////////////////
|
||||
// Variable expression //
|
||||
/////////////////////////
|
||||
ExprNode *VarExprNode::semant( Environ *e ){
|
||||
var->semant( e );
|
||||
sem_type=var->sem_type;
|
||||
ConstType *c=sem_type->constType();
|
||||
if( !c ) return this;
|
||||
ExprNode *expr=constValue( c );
|
||||
delete this;return expr;
|
||||
ExprNode *VarExprNode::semant(Environ *e) {
|
||||
var->semant(e);
|
||||
sem_type = var->sem_type;
|
||||
ConstType *c = sem_type->constType();
|
||||
if (!c) return this;
|
||||
ExprNode *expr = constValue(c);
|
||||
delete this; return expr;
|
||||
}
|
||||
|
||||
TNode *VarExprNode::translate( Codegen *g ){
|
||||
return var->load( g );
|
||||
TNode *VarExprNode::translate(Codegen *g) {
|
||||
return var->load(g);
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// Integer constant //
|
||||
//////////////////////
|
||||
IntConstNode::IntConstNode( int n ):value(n){
|
||||
sem_type=Type::int_type;
|
||||
IntConstNode::IntConstNode(int n) :value(n) {
|
||||
sem_type = Type::int_type;
|
||||
}
|
||||
|
||||
TNode *IntConstNode::translate( Codegen *g ){
|
||||
return d_new TNode( IR_CONST,0,0,value );
|
||||
TNode *IntConstNode::translate(Codegen *g) {
|
||||
return d_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(){
|
||||
return itoa( value );
|
||||
string IntConstNode::stringValue() {
|
||||
return itoa(value);
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// Float constant //
|
||||
////////////////////
|
||||
FloatConstNode::FloatConstNode( float f ):value(f){
|
||||
sem_type=Type::float_type;
|
||||
FloatConstNode::FloatConstNode(float f) :value(f) {
|
||||
sem_type = Type::float_type;
|
||||
}
|
||||
|
||||
TNode *FloatConstNode::translate( Codegen *g ){
|
||||
return d_new TNode( IR_CONST,0,0,*(int*)&value );
|
||||
TNode *FloatConstNode::translate(Codegen *g) {
|
||||
return d_new TNode(IR_CONST, 0, 0, *(int*)&value);
|
||||
}
|
||||
|
||||
int FloatConstNode::intValue(){
|
||||
float flt=value;
|
||||
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 );
|
||||
_asm{
|
||||
fld [flt];
|
||||
fistp [temp];
|
||||
_control87(_RC_NEAR | _PC_24 | _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT | _EM_DENORMAL, 0xfffff);
|
||||
_asm {
|
||||
fld[flt];
|
||||
fistp[temp];
|
||||
}
|
||||
_control87( _CW_DEFAULT,0xfffff );
|
||||
_control87(_CW_DEFAULT, 0xfffff);
|
||||
return temp;
|
||||
}
|
||||
|
||||
float FloatConstNode::floatValue(){
|
||||
float FloatConstNode::floatValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
string FloatConstNode::stringValue(){
|
||||
return ftoa( value );
|
||||
string FloatConstNode::stringValue() {
|
||||
return ftoa(value);
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// String constant //
|
||||
/////////////////////
|
||||
StringConstNode::StringConstNode( const string &s ):value(s){
|
||||
sem_type=Type::string_type;
|
||||
StringConstNode::StringConstNode(const string &s) :value(s) {
|
||||
sem_type = Type::string_type;
|
||||
}
|
||||
|
||||
TNode *StringConstNode::translate( Codegen *g ){
|
||||
string lab=genLabel();
|
||||
g->s_data( value,lab );
|
||||
return call( "__bbStrConst",global( lab ) );
|
||||
TNode *StringConstNode::translate(Codegen *g) {
|
||||
string lab = genLabel();
|
||||
g->s_data(value, lab);
|
||||
return call("__bbStrConst", global(lab));
|
||||
}
|
||||
|
||||
int StringConstNode::intValue(){
|
||||
return atoi( value );
|
||||
int StringConstNode::intValue() {
|
||||
return atoi(value);
|
||||
}
|
||||
|
||||
float StringConstNode::floatValue(){
|
||||
return (float)atof( value );
|
||||
float StringConstNode::floatValue() {
|
||||
return (float)atof(value);
|
||||
}
|
||||
|
||||
string StringConstNode::stringValue(){
|
||||
string StringConstNode::stringValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// Unary operator //
|
||||
////////////////////
|
||||
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( ConstNode *c=expr->constNode() ){
|
||||
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 (ConstNode *c = expr->constNode()) {
|
||||
ExprNode *e;
|
||||
if( sem_type==Type::int_type ){
|
||||
switch( op ){
|
||||
case '+':e=d_new IntConstNode( +c->intValue() );break;
|
||||
case '-':e=d_new IntConstNode( -c->intValue() );break;
|
||||
case ABS:e=d_new IntConstNode( c->intValue()>=0 ? c->intValue() : -c->intValue() );break;
|
||||
case SGN:e=d_new IntConstNode( c->intValue()>0 ? 1 : (c->intValue()<0 ? -1 : 0) );break;
|
||||
if (sem_type == Type::int_type) {
|
||||
switch (op) {
|
||||
case '+':e = d_new IntConstNode(+c->intValue()); break;
|
||||
case '-':e = d_new IntConstNode(-c->intValue()); break;
|
||||
case ABS:e = d_new IntConstNode(c->intValue() >= 0 ? c->intValue() : -c->intValue()); break;
|
||||
case SGN:e = d_new IntConstNode(c->intValue() > 0 ? 1 : (c->intValue() < 0 ? -1 : 0)); break;
|
||||
}
|
||||
}else{
|
||||
switch( op ){
|
||||
case '+':e=d_new FloatConstNode( +c->floatValue() );break;
|
||||
case '-':e=d_new FloatConstNode( -c->floatValue() );break;
|
||||
case ABS:e=d_new FloatConstNode( c->floatValue()>=0 ? c->floatValue() : -c->floatValue() );break;
|
||||
case SGN:e=d_new FloatConstNode( c->floatValue()>0 ? 1 : (c->floatValue()<0 ? -1 : 0) );break;
|
||||
} else {
|
||||
switch (op) {
|
||||
case '+':e = d_new FloatConstNode(+c->floatValue()); break;
|
||||
case '-':e = d_new FloatConstNode(-c->floatValue()); break;
|
||||
case ABS:e = d_new FloatConstNode(c->floatValue() >= 0 ? c->floatValue() : -c->floatValue()); break;
|
||||
case SGN:e = d_new FloatConstNode(c->floatValue() > 0 ? 1 : (c->floatValue() < 0 ? -1 : 0)); break;
|
||||
}
|
||||
}
|
||||
delete this;
|
||||
return e;
|
||||
return e = nullptr;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
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 );
|
||||
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);
|
||||
}
|
||||
}else{
|
||||
switch( op ){
|
||||
case '+':return l;
|
||||
case '-':n=IR_FNEG;break;
|
||||
case ABS:return fcall( "__bbFAbs",l );
|
||||
case SGN:return fcall( "__bbFSgn",l );
|
||||
} else {
|
||||
switch (op) {
|
||||
case '+':return l;
|
||||
case '-':n = IR_FNEG; break;
|
||||
case ABS:return fcall("__bbFAbs", l);
|
||||
case SGN:return fcall("__bbFSgn", l);
|
||||
}
|
||||
}
|
||||
return d_new TNode( n,l,0 );
|
||||
return d_new TNode(n, l, 0);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// 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 );
|
||||
ConstNode *lc=lhs->constNode(),*rc=rhs->constNode();
|
||||
if( lc && rc ){
|
||||
ExprNode *expr;
|
||||
switch( op ){
|
||||
case AND:expr=d_new IntConstNode( lc->intValue() & rc->intValue() );break;
|
||||
case OR: expr=d_new IntConstNode( lc->intValue() | rc->intValue() );break;
|
||||
case XOR:expr=d_new IntConstNode( lc->intValue() ^ rc->intValue() );break;
|
||||
case SHL:expr=d_new IntConstNode( lc->intValue()<< rc->intValue() );break;
|
||||
case SHR:expr=d_new IntConstNode( (unsigned)lc->intValue()>>rc->intValue() );break;
|
||||
case SAR:expr=d_new IntConstNode( lc->intValue()>> rc->intValue() );break;
|
||||
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 = d_new IntConstNode(lc->intValue() & rc->intValue()); break;
|
||||
case OR: expr = d_new IntConstNode(lc->intValue() | rc->intValue()); break;
|
||||
case XOR:expr = d_new IntConstNode(lc->intValue() ^ rc->intValue()); break;
|
||||
case SHL:expr = d_new IntConstNode(lc->intValue() << rc->intValue()); break;
|
||||
case SHR:expr = d_new IntConstNode((unsigned)lc->intValue() >> rc->intValue()); break;
|
||||
case SAR:expr = d_new IntConstNode(lc->intValue() >> rc->intValue()); break;
|
||||
}
|
||||
delete this;
|
||||
return expr;
|
||||
}
|
||||
sem_type=Type::int_type;
|
||||
sem_type = Type::int_type;
|
||||
return this;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
return d_new TNode( n,l,r );
|
||||
return d_new TNode(n, l, r);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// arithmetic expression //
|
||||
///////////////////////////
|
||||
ExprNode *ArithExprNode::semant( Environ *e ){
|
||||
lhs=lhs->semant(e);
|
||||
rhs=rhs->semant(e);
|
||||
if( lhs->sem_type->structType() || rhs->sem_type->structType() ){
|
||||
ex( "Arithmetic operator cannot be applied to custom type objects" );
|
||||
ExprNode *ArithExprNode::semant(Environ *e) {
|
||||
lhs = lhs->semant(e);
|
||||
rhs = rhs->semant(e);
|
||||
if (lhs->sem_type->structType() || rhs->sem_type->structType()) {
|
||||
ex("Arithmetic operator cannot be applied to custom type objects");
|
||||
}
|
||||
if( lhs->sem_type==Type::string_type || rhs->sem_type==Type::string_type ){
|
||||
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" );
|
||||
sem_type=Type::string_type;
|
||||
}else if( op=='^' || lhs->sem_type==Type::float_type || rhs->sem_type==Type::float_type ){
|
||||
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
|
||||
sem_type=Type::float_type;
|
||||
}else{
|
||||
sem_type = Type::float_type;
|
||||
} else {
|
||||
//must be 2 ints
|
||||
sem_type=Type::int_type;
|
||||
sem_type = Type::int_type;
|
||||
}
|
||||
lhs=lhs->castTo( sem_type,e );
|
||||
rhs=rhs->castTo( sem_type,e );
|
||||
ConstNode *lc=lhs->constNode(),*rc=rhs->constNode();
|
||||
if( rc && (op=='/' || op==MOD) ){
|
||||
if( (sem_type==Type::int_type && !rc->intValue()) || (sem_type==Type::float_type && !rc->floatValue()) ){
|
||||
ex( "Division by zero" );
|
||||
lhs = lhs->castTo(sem_type, e);
|
||||
rhs = rhs->castTo(sem_type, e);
|
||||
ConstNode *lc = lhs->constNode(), *rc = rhs->constNode();
|
||||
if (rc && (op == '/' || op == MOD)) {
|
||||
if ((sem_type == Type::int_type && !rc->intValue()) || (sem_type == Type::float_type && !rc->floatValue())) {
|
||||
ex("Division by zero");
|
||||
}
|
||||
}
|
||||
if( lc && rc ){
|
||||
ExprNode *expr;
|
||||
if( sem_type==Type::string_type ){
|
||||
expr=d_new StringConstNode( lc->stringValue()+rc->stringValue() );
|
||||
}else if( sem_type==Type::int_type ){
|
||||
switch( op ){
|
||||
case '+':expr=d_new IntConstNode( lc->intValue()+rc->intValue() );break;
|
||||
case '-':expr=d_new IntConstNode( lc->intValue()-rc->intValue() );break;
|
||||
case '*':expr=d_new IntConstNode( lc->intValue()*rc->intValue() );break;
|
||||
case '/':expr=d_new IntConstNode( lc->intValue()/rc->intValue() );break;
|
||||
case MOD:expr=d_new IntConstNode( lc->intValue()%rc->intValue() );break;
|
||||
if (lc && rc) {
|
||||
ExprNode *expr = nullptr;
|
||||
if (sem_type == Type::string_type) {
|
||||
expr = d_new StringConstNode(lc->stringValue() + rc->stringValue());
|
||||
} else if (sem_type == Type::int_type) {
|
||||
switch (op) {
|
||||
case '+':expr = d_new IntConstNode(lc->intValue() + rc->intValue()); break;
|
||||
case '-':expr = d_new IntConstNode(lc->intValue() - rc->intValue()); break;
|
||||
case '*':expr = d_new IntConstNode(lc->intValue()*rc->intValue()); break;
|
||||
case '/':expr = d_new IntConstNode(lc->intValue() / rc->intValue()); break;
|
||||
case MOD:expr = d_new IntConstNode(lc->intValue() % rc->intValue()); break;
|
||||
}
|
||||
}else{
|
||||
switch( op ){
|
||||
case '+':expr=d_new FloatConstNode( lc->floatValue()+rc->floatValue() );break;
|
||||
case '-':expr=d_new FloatConstNode( lc->floatValue()-rc->floatValue() );break;
|
||||
case '*':expr=d_new FloatConstNode( lc->floatValue()*rc->floatValue() );break;
|
||||
case '/':expr=d_new FloatConstNode( lc->floatValue()/rc->floatValue() );break;
|
||||
case MOD:expr=d_new FloatConstNode( fmod( lc->floatValue(),rc->floatValue() ) );break;
|
||||
case '^':expr=d_new FloatConstNode( pow( lc->floatValue(),rc->floatValue() ) );break;
|
||||
} else {
|
||||
switch (op) {
|
||||
case '+':expr = d_new FloatConstNode(lc->floatValue() + rc->floatValue()); break;
|
||||
case '-':expr = d_new FloatConstNode(lc->floatValue() - rc->floatValue()); break;
|
||||
case '*':expr = d_new FloatConstNode(lc->floatValue()*rc->floatValue()); break;
|
||||
case '/':expr = d_new FloatConstNode(lc->floatValue() / rc->floatValue()); break;
|
||||
case MOD:expr = d_new FloatConstNode(fmod(lc->floatValue(), rc->floatValue())); break;
|
||||
case '^':expr = d_new FloatConstNode(pow(lc->floatValue(), rc->floatValue())); break;
|
||||
}
|
||||
}
|
||||
delete this;
|
||||
@@ -421,78 +422,78 @@ ExprNode *ArithExprNode::semant( Environ *e ){
|
||||
return this;
|
||||
}
|
||||
|
||||
TNode *ArithExprNode::translate( Codegen *g ){
|
||||
TNode *l=lhs->translate( g );
|
||||
TNode *r=rhs->translate( g );
|
||||
if( sem_type==Type::string_type ){
|
||||
return call( "__bbStrConcat",l,r );
|
||||
TNode *ArithExprNode::translate(Codegen *g) {
|
||||
TNode *l = lhs->translate(g);
|
||||
TNode *r = rhs->translate(g);
|
||||
if (sem_type == Type::string_type) {
|
||||
return call("__bbStrConcat", l, r);
|
||||
}
|
||||
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 );
|
||||
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);
|
||||
}
|
||||
}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 );
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
return d_new TNode( n,l,r );
|
||||
return d_new TNode(n, l, r);
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// relation expression //
|
||||
/////////////////////////
|
||||
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" );
|
||||
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;
|
||||
}else if( lhs->sem_type==Type::float_type || rhs->sem_type==Type::float_type ){
|
||||
opType=Type::float_type;
|
||||
}else{
|
||||
opType=Type::int_type;
|
||||
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");
|
||||
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;
|
||||
} else if (lhs->sem_type == Type::float_type || rhs->sem_type == Type::float_type) {
|
||||
opType = Type::float_type;
|
||||
} else {
|
||||
opType = Type::int_type;
|
||||
}
|
||||
sem_type=Type::int_type;
|
||||
lhs=lhs->castTo( opType,e );
|
||||
rhs=rhs->castTo( opType,e );
|
||||
ConstNode *lc=lhs->constNode(),*rc=rhs->constNode();
|
||||
if( lc && rc ){
|
||||
ExprNode *expr;
|
||||
if( opType==Type::string_type ){
|
||||
switch( op ){
|
||||
case '<':expr=d_new IntConstNode( lc->stringValue()< rc->stringValue() );break;
|
||||
case '=':expr=d_new IntConstNode( lc->stringValue()==rc->stringValue() );break;
|
||||
case '>':expr=d_new IntConstNode( lc->stringValue()> rc->stringValue() );break;
|
||||
case LE: expr=d_new IntConstNode( lc->stringValue()<=rc->stringValue() );break;
|
||||
case NE: expr=d_new IntConstNode( lc->stringValue()!=rc->stringValue() );break;
|
||||
case GE: expr=d_new IntConstNode( lc->stringValue()>=rc->stringValue() );break;
|
||||
sem_type = Type::int_type;
|
||||
lhs = lhs->castTo(opType, e);
|
||||
rhs = rhs->castTo(opType, e);
|
||||
ConstNode *lc = lhs->constNode(), *rc = rhs->constNode();
|
||||
if (lc && rc) {
|
||||
ExprNode *expr = nullptr;
|
||||
if (opType == Type::string_type) {
|
||||
switch (op) {
|
||||
case '<':expr = d_new IntConstNode(lc->stringValue() < rc->stringValue()); break;
|
||||
case '=':expr = d_new IntConstNode(lc->stringValue() == rc->stringValue()); break;
|
||||
case '>':expr = d_new IntConstNode(lc->stringValue() > rc->stringValue()); break;
|
||||
case LE: expr = d_new IntConstNode(lc->stringValue() <= rc->stringValue()); break;
|
||||
case NE: expr = d_new IntConstNode(lc->stringValue() != rc->stringValue()); break;
|
||||
case GE: expr = d_new IntConstNode(lc->stringValue() >= rc->stringValue()); break;
|
||||
}
|
||||
}else if( opType==Type::float_type ){
|
||||
switch( op ){
|
||||
case '<':expr=d_new IntConstNode( lc->floatValue()< rc->floatValue() );break;
|
||||
case '=':expr=d_new IntConstNode( lc->floatValue()==rc->floatValue() );break;
|
||||
case '>':expr=d_new IntConstNode( lc->floatValue()> rc->floatValue() );break;
|
||||
case LE: expr=d_new IntConstNode( lc->floatValue()<=rc->floatValue() );break;
|
||||
case NE: expr=d_new IntConstNode( lc->floatValue()!=rc->floatValue() );break;
|
||||
case GE: expr=d_new IntConstNode( lc->floatValue()>=rc->floatValue() );break;
|
||||
} else if (opType == Type::float_type) {
|
||||
switch (op) {
|
||||
case '<':expr = d_new IntConstNode(lc->floatValue() < rc->floatValue()); break;
|
||||
case '=':expr = d_new IntConstNode(lc->floatValue() == rc->floatValue()); break;
|
||||
case '>':expr = d_new IntConstNode(lc->floatValue() > rc->floatValue()); break;
|
||||
case LE: expr = d_new IntConstNode(lc->floatValue() <= rc->floatValue()); break;
|
||||
case NE: expr = d_new IntConstNode(lc->floatValue() != rc->floatValue()); break;
|
||||
case GE: expr = d_new IntConstNode(lc->floatValue() >= rc->floatValue()); break;
|
||||
}
|
||||
}else{
|
||||
switch( op ){
|
||||
case '<':expr=d_new IntConstNode( lc->intValue()< rc->intValue() );break;
|
||||
case '=':expr=d_new IntConstNode( lc->intValue()==rc->intValue() );break;
|
||||
case '>':expr=d_new IntConstNode( lc->intValue()> rc->intValue() );break;
|
||||
case LE: expr=d_new IntConstNode( lc->intValue()<=rc->intValue() );break;
|
||||
case NE: expr=d_new IntConstNode( lc->intValue()!=rc->intValue() );break;
|
||||
case GE: expr=d_new IntConstNode( lc->intValue()>=rc->intValue() );break;
|
||||
} else {
|
||||
switch (op) {
|
||||
case '<':expr = d_new IntConstNode(lc->intValue() < rc->intValue()); break;
|
||||
case '=':expr = d_new IntConstNode(lc->intValue() == rc->intValue()); break;
|
||||
case '>':expr = d_new IntConstNode(lc->intValue() > rc->intValue()); break;
|
||||
case LE: expr = d_new IntConstNode(lc->intValue() <= rc->intValue()); break;
|
||||
case NE: expr = d_new IntConstNode(lc->intValue() != rc->intValue()); break;
|
||||
case GE: expr = d_new IntConstNode(lc->intValue() >= rc->intValue()); break;
|
||||
}
|
||||
}
|
||||
delete this;
|
||||
@@ -501,127 +502,127 @@ ExprNode *RelExprNode::semant( Environ *e ){
|
||||
return this;
|
||||
}
|
||||
|
||||
TNode *RelExprNode::translate( Codegen *g ){
|
||||
TNode *l=lhs->translate( g );
|
||||
TNode *r=rhs->translate( g );
|
||||
return compare( op,l,r,opType );
|
||||
TNode *RelExprNode::translate(Codegen *g) {
|
||||
TNode *l = lhs->translate(g);
|
||||
TNode *r = rhs->translate(g);
|
||||
return compare(op, l, r, opType);
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// New expression //
|
||||
////////////////////
|
||||
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" );
|
||||
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");
|
||||
return this;
|
||||
}
|
||||
|
||||
TNode *NewNode::translate( Codegen *g ){
|
||||
return call( "__bbObjNew",global( "_t"+ident ) );
|
||||
TNode *NewNode::translate(Codegen *g) {
|
||||
return call("__bbObjNew", global("_t" + ident));
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// First of class //
|
||||
////////////////////
|
||||
ExprNode *FirstNode::semant( Environ *e ){
|
||||
sem_type=e->findType( ident );
|
||||
if( !sem_type ) ex( "custom type name name not found" );
|
||||
ExprNode *FirstNode::semant(Environ *e) {
|
||||
sem_type = e->findType(ident);
|
||||
if (!sem_type) ex("custom type name name not found");
|
||||
return this;
|
||||
}
|
||||
|
||||
TNode *FirstNode::translate( Codegen *g ){
|
||||
return call( "__bbObjFirst",global( "_t"+ident ) );
|
||||
TNode *FirstNode::translate(Codegen *g) {
|
||||
return call("__bbObjFirst", global("_t" + ident));
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// Last of class //
|
||||
///////////////////
|
||||
ExprNode *LastNode::semant( Environ *e ){
|
||||
sem_type=e->findType( ident );
|
||||
if( !sem_type ) ex( "custom type name not found" );
|
||||
ExprNode *LastNode::semant(Environ *e) {
|
||||
sem_type = e->findType(ident);
|
||||
if (!sem_type) ex("custom type name not found");
|
||||
return this;
|
||||
}
|
||||
|
||||
TNode *LastNode::translate( Codegen *g ){
|
||||
return call( "__bbObjLast",global( "_t"+ident ) );
|
||||
TNode *LastNode::translate(Codegen *g) {
|
||||
return call("__bbObjLast", global("_t" + ident));
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// Next of object //
|
||||
////////////////////
|
||||
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" );
|
||||
sem_type=expr->sem_type;
|
||||
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");
|
||||
sem_type = expr->sem_type;
|
||||
return this;
|
||||
}
|
||||
|
||||
TNode *AfterNode::translate( Codegen *g ){
|
||||
TNode *t=expr->translate( g );
|
||||
if( g->debug ) t=jumpf( t,"__bbNullObjEx" );
|
||||
return call( "__bbObjNext",t );
|
||||
TNode *AfterNode::translate(Codegen *g) {
|
||||
TNode *t = expr->translate(g);
|
||||
if (g->debug) t = jumpf(t, "__bbNullObjEx");
|
||||
return call("__bbObjNext", t);
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// Prev of object //
|
||||
////////////////////
|
||||
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" );
|
||||
sem_type=expr->sem_type;
|
||||
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");
|
||||
sem_type = expr->sem_type;
|
||||
return this;
|
||||
}
|
||||
|
||||
TNode *BeforeNode::translate( Codegen *g ){
|
||||
TNode *t=expr->translate( g );
|
||||
if( g->debug ) t=jumpf( t,"__bbNullObjEx" );
|
||||
return call( "__bbObjPrev",t );
|
||||
TNode *BeforeNode::translate(Codegen *g) {
|
||||
TNode *t = expr->translate(g);
|
||||
if (g->debug) t = jumpf(t, "__bbNullObjEx");
|
||||
return call("__bbObjPrev", t);
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Null object //
|
||||
/////////////////
|
||||
ExprNode *NullNode::semant( Environ *e ){
|
||||
sem_type=Type::null_type;
|
||||
ExprNode *NullNode::semant(Environ *e) {
|
||||
sem_type = Type::null_type;
|
||||
return this;
|
||||
}
|
||||
|
||||
TNode *NullNode::translate( Codegen *g ){
|
||||
return d_new TNode( IR_CONST,0,0,0 );
|
||||
TNode *NullNode::translate(Codegen *g) {
|
||||
return d_new TNode(IR_CONST, 0, 0, 0);
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Object cast //
|
||||
/////////////////
|
||||
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" );
|
||||
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");
|
||||
return this;
|
||||
}
|
||||
|
||||
TNode *ObjectCastNode::translate( Codegen *g ){
|
||||
TNode *t=expr->translate( g );
|
||||
t=call( "__bbObjFromHandle",t,global( "_t"+sem_type->structType()->ident ) );
|
||||
TNode *ObjectCastNode::translate(Codegen *g) {
|
||||
TNode *t = expr->translate(g);
|
||||
t = call("__bbObjFromHandle", t, global("_t" + sem_type->structType()->ident));
|
||||
return t;
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// Object Handle //
|
||||
///////////////////
|
||||
ExprNode *ObjectHandleNode::semant( Environ *e ){
|
||||
expr=expr->semant( e );
|
||||
if( !expr->sem_type->structType() ) ex( "'ObjectHandle' must be used with an object" );
|
||||
sem_type=Type::int_type;
|
||||
ExprNode *ObjectHandleNode::semant(Environ *e) {
|
||||
expr = expr->semant(e);
|
||||
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 *t=expr->translate( g );
|
||||
return call( "__bbObjToHandle",t );
|
||||
TNode *ObjectHandleNode::translate(Codegen *g) {
|
||||
TNode *t = expr->translate(g);
|
||||
return call("__bbObjToHandle", t);
|
||||
}
|
||||
|
||||
+106
-106
@@ -6,188 +6,188 @@
|
||||
|
||||
struct ConstNode; //is constant int,float or string
|
||||
|
||||
struct ExprNode : public Node{
|
||||
struct ExprNode : public Node {
|
||||
Type *sem_type;
|
||||
ExprNode():sem_type(0){}
|
||||
ExprNode( Type *t ):sem_type( t ){}
|
||||
ExprNode() :sem_type(0) {}
|
||||
ExprNode(Type *t) :sem_type(t) {}
|
||||
|
||||
ExprNode *castTo( Type *ty,Environ *e );
|
||||
ExprNode *semant( Environ *e,Type *ty );
|
||||
ExprNode *castTo(Type *ty, Environ *e);
|
||||
ExprNode *semant(Environ *e, Type *ty);
|
||||
|
||||
virtual ExprNode *semant( Environ *e )=0;
|
||||
virtual TNode *translate( Codegen *g )=0;
|
||||
virtual ConstNode *constNode(){ return 0; }
|
||||
virtual ExprNode *semant(Environ *e) = 0;
|
||||
virtual TNode *translate(Codegen *g) = 0;
|
||||
virtual ConstNode *constNode() { return 0; }
|
||||
};
|
||||
|
||||
struct ExprSeqNode : public Node{
|
||||
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(); }
|
||||
void semant( Environ *e );
|
||||
TNode *translate( Codegen *g,bool userlib );
|
||||
void castTo( DeclSeq *ds,Environ *e,bool userlib );
|
||||
void castTo( Type *t,Environ *e );
|
||||
~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);
|
||||
void castTo(Type *t, Environ *e);
|
||||
};
|
||||
|
||||
#include "varnode.h"
|
||||
|
||||
struct CastNode : public ExprNode{
|
||||
struct CastNode : public ExprNode {
|
||||
ExprNode *expr;
|
||||
Type *type;
|
||||
CastNode( ExprNode *ex,Type *ty ):expr( ex ),type( ty ){}
|
||||
~CastNode(){ delete expr; }
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
CastNode(ExprNode *ex, Type *ty) :expr(ex), type(ty) {}
|
||||
~CastNode() { delete expr; }
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
struct CallNode : public ExprNode{
|
||||
string ident,tag;
|
||||
struct CallNode : public ExprNode {
|
||||
string ident, tag;
|
||||
ExprSeqNode *exprs;
|
||||
Decl *sem_decl;
|
||||
CallNode( const string &i,const string &t,ExprSeqNode *e ):ident(i),tag(t),exprs(e){}
|
||||
~CallNode(){ delete exprs; }
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
CallNode(const string &i, const string &t, ExprSeqNode *e) :ident(i), tag(t), exprs(e) {}
|
||||
~CallNode() { delete exprs; }
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
struct VarExprNode : public ExprNode{
|
||||
struct VarExprNode : public ExprNode {
|
||||
VarNode *var;
|
||||
VarExprNode( VarNode *v ):var(v){}
|
||||
~VarExprNode(){ delete var; }
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
VarExprNode(VarNode *v) :var(v) {}
|
||||
~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; }
|
||||
virtual int intValue()=0;
|
||||
virtual float floatValue()=0;
|
||||
virtual string stringValue()=0;
|
||||
struct ConstNode : public ExprNode {
|
||||
ExprNode *semant(Environ *e) { return this; }
|
||||
ConstNode *constNode() { return this; }
|
||||
virtual int intValue() = 0;
|
||||
virtual float floatValue() = 0;
|
||||
virtual string stringValue() = 0;
|
||||
};
|
||||
|
||||
struct IntConstNode : public ConstNode{
|
||||
struct IntConstNode : public ConstNode {
|
||||
int value;
|
||||
IntConstNode( int n );
|
||||
TNode *translate( Codegen *g );
|
||||
IntConstNode(int n);
|
||||
TNode *translate(Codegen *g);
|
||||
int intValue();
|
||||
float floatValue();
|
||||
string stringValue();
|
||||
};
|
||||
|
||||
struct FloatConstNode : public ConstNode{
|
||||
struct FloatConstNode : public ConstNode {
|
||||
float value;
|
||||
FloatConstNode( float f );
|
||||
TNode *translate( Codegen *g );
|
||||
FloatConstNode(float f);
|
||||
TNode *translate(Codegen *g);
|
||||
int intValue();
|
||||
float floatValue();
|
||||
string stringValue();
|
||||
};
|
||||
|
||||
struct StringConstNode : public ConstNode{
|
||||
struct StringConstNode : public ConstNode {
|
||||
string value;
|
||||
StringConstNode( const string &s );
|
||||
TNode *translate( Codegen *g );
|
||||
StringConstNode(const string &s);
|
||||
TNode *translate(Codegen *g);
|
||||
int intValue();
|
||||
float floatValue();
|
||||
string stringValue();
|
||||
};
|
||||
|
||||
struct UniExprNode : public ExprNode{
|
||||
int op;ExprNode *expr;
|
||||
UniExprNode( int op,ExprNode *expr ):op( op ),expr( expr ){}
|
||||
~UniExprNode(){ delete expr; }
|
||||
struct UniExprNode : public ExprNode {
|
||||
int op; ExprNode *expr;
|
||||
UniExprNode(int op, ExprNode *expr) :op(op), expr(expr) {}
|
||||
~UniExprNode() { delete expr; }
|
||||
ExprNode *constize();
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
// and, or, eor, lsl, lsr, asr
|
||||
struct BinExprNode : public ExprNode{
|
||||
int op;ExprNode *lhs,*rhs;
|
||||
BinExprNode( int op,ExprNode *lhs,ExprNode *rhs ):op( op ),lhs( lhs ),rhs( rhs ){}
|
||||
~BinExprNode(){ delete lhs;delete rhs; }
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
struct BinExprNode : public ExprNode {
|
||||
int op; ExprNode *lhs, *rhs;
|
||||
BinExprNode(int op, ExprNode *lhs, ExprNode *rhs) :op(op), lhs(lhs), rhs(rhs) {}
|
||||
~BinExprNode() { delete lhs; delete rhs; }
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
// *,/,Mod,+,-
|
||||
struct ArithExprNode : public ExprNode{
|
||||
int op;ExprNode *lhs,*rhs;
|
||||
ArithExprNode( int op,ExprNode *lhs,ExprNode *rhs ):op( op ),lhs( lhs ),rhs( rhs ){}
|
||||
~ArithExprNode(){ delete lhs;delete rhs; }
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
struct ArithExprNode : public ExprNode {
|
||||
int op; ExprNode *lhs, *rhs;
|
||||
ArithExprNode(int op, ExprNode *lhs, ExprNode *rhs) :op(op), lhs(lhs), rhs(rhs) {}
|
||||
~ArithExprNode() { delete lhs; delete rhs; }
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
//<,=,>,<=,<>,>=
|
||||
struct RelExprNode : public ExprNode{
|
||||
int op;ExprNode *lhs,*rhs;
|
||||
struct RelExprNode : public ExprNode {
|
||||
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; }
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
RelExprNode(int op, ExprNode *lhs, ExprNode *rhs) :op(op), lhs(lhs), rhs(rhs) {}
|
||||
~RelExprNode() { delete lhs; delete rhs; }
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
struct NewNode : public ExprNode{
|
||||
struct NewNode : public ExprNode {
|
||||
string ident;
|
||||
NewNode( const string &i ):ident(i){}
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
NewNode(const string &i) :ident(i) {}
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
struct FirstNode : public ExprNode{
|
||||
struct FirstNode : public ExprNode {
|
||||
string ident;
|
||||
FirstNode( const string &i ):ident(i){}
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
FirstNode(const string &i) :ident(i) {}
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
struct LastNode : public ExprNode{
|
||||
struct LastNode : public ExprNode {
|
||||
string ident;
|
||||
LastNode( const string &i ):ident(i){}
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
LastNode(const string &i) :ident(i) {}
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
struct AfterNode : public ExprNode{
|
||||
struct AfterNode : public ExprNode {
|
||||
ExprNode *expr;
|
||||
AfterNode( ExprNode *e ):expr(e){}
|
||||
~AfterNode(){ delete expr; }
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
AfterNode(ExprNode *e) :expr(e) {}
|
||||
~AfterNode() { delete expr; }
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
struct BeforeNode : public ExprNode{
|
||||
struct BeforeNode : public ExprNode {
|
||||
ExprNode *expr;
|
||||
BeforeNode( ExprNode *e ):expr(e){}
|
||||
~BeforeNode(){ delete expr; }
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
BeforeNode(ExprNode *e) :expr(e) {}
|
||||
~BeforeNode() { delete expr; }
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
struct NullNode : public ExprNode{
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
struct NullNode : public ExprNode {
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
struct ObjectCastNode : public ExprNode{
|
||||
struct ObjectCastNode : public ExprNode {
|
||||
ExprNode *expr;
|
||||
string type_ident;
|
||||
ObjectCastNode( ExprNode *e,const string &t ):expr(e),type_ident(t){}
|
||||
~ObjectCastNode(){ delete expr; }
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
ObjectCastNode(ExprNode *e, const string &t) :expr(e), type_ident(t) {}
|
||||
~ObjectCastNode() { delete expr; }
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
struct ObjectHandleNode : public ExprNode{
|
||||
struct ObjectHandleNode : public ExprNode {
|
||||
ExprNode *expr;
|
||||
ObjectHandleNode( ExprNode *e ):expr(e){}
|
||||
~ObjectHandleNode(){ delete expr; }
|
||||
ExprNode *semant( Environ *e );
|
||||
TNode *translate( Codegen *g );
|
||||
ObjectHandleNode(ExprNode *e) :expr(e) {}
|
||||
~ObjectHandleNode() { delete expr; }
|
||||
ExprNode *semant(Environ *e);
|
||||
TNode *translate(Codegen *g);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ TNode *Node::createVars( Environ *e ){
|
||||
// release local vars //
|
||||
////////////////////////
|
||||
TNode *Node::deleteVars( Environ *e ){
|
||||
TNode *t=0,*l=0,*p,*p1,*p2;
|
||||
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];
|
||||
Type *type=d->type;
|
||||
|
||||
+340
-341
@@ -3,301 +3,299 @@
|
||||
#include "nodes.h"
|
||||
|
||||
static string fileLabel;
|
||||
static map<string,string> fileMap;
|
||||
static map<string, string> fileMap;
|
||||
|
||||
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 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 ){
|
||||
fileLabel="";
|
||||
void StmtSeqNode::reset(const string &file, const string &lab) {
|
||||
fileLabel = "";
|
||||
fileMap.clear();
|
||||
|
||||
fileMap[file]=lab;
|
||||
fileMap[file] = lab;
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
// Statement Sequence //
|
||||
////////////////////////
|
||||
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;
|
||||
throw;
|
||||
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;
|
||||
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 ){
|
||||
StmtNode *stmt=stmts[k];
|
||||
stmt->debug( stmts[k]->pos,g );
|
||||
try{
|
||||
stmt->translate( g );
|
||||
}
|
||||
catch( Ex &x ){
|
||||
if( x.pos<0 ) x.pos=stmts[k]->pos;
|
||||
if( !x.file.size() ) x.file=file;
|
||||
throw;
|
||||
string t = fileLabel;
|
||||
fileLabel = file.size() ? fileMap[file] : "";
|
||||
for (int k = 0; k < stmts.size(); ++k) {
|
||||
StmtNode *stmt = stmts[k];
|
||||
stmt->debug(stmts[k]->pos, g);
|
||||
try {
|
||||
stmt->translate(g);
|
||||
} catch (Ex &x) {
|
||||
if (x.pos < 0) x.pos = stmts[k]->pos;
|
||||
if (!x.file.size()) x.file = file;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
fileLabel=t;
|
||||
fileLabel = t;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// An Include! //
|
||||
/////////////////
|
||||
void IncludeNode::semant( Environ *e ){
|
||||
void IncludeNode::semant(Environ *e) {
|
||||
|
||||
label=genLabel();
|
||||
fileMap[file]=label;
|
||||
|
||||
stmts->semant( e );
|
||||
label = genLabel();
|
||||
fileMap[file] = label;
|
||||
|
||||
stmts->semant(e);
|
||||
}
|
||||
|
||||
void IncludeNode::translate( Codegen *g ){
|
||||
void IncludeNode::translate(Codegen *g) {
|
||||
|
||||
if( g->debug ) g->s_data( file,label );
|
||||
if (g->debug) g->s_data(file, label);
|
||||
|
||||
stmts->translate( g );
|
||||
stmts->translate(g);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// a declaration //
|
||||
///////////////////
|
||||
void DeclStmtNode::semant( Environ *e ){
|
||||
decl->proto( e->decls,e );
|
||||
decl->semant( e );
|
||||
void DeclStmtNode::semant(Environ *e) {
|
||||
decl->proto(e->decls, e);
|
||||
decl->semant(e);
|
||||
}
|
||||
|
||||
void DeclStmtNode::translate( Codegen *g ){
|
||||
decl->translate( g );
|
||||
void DeclStmtNode::translate(Codegen *g) {
|
||||
decl->translate(g);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Dim AND declare an Array //
|
||||
//////////////////////////////
|
||||
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" );
|
||||
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;
|
||||
}else{
|
||||
if( e->level>0 ) ex( "Array not found in main program" );
|
||||
if( !t ) t=Type::int_type;
|
||||
sem_type=d_new ArrayType( t,exprs->size() );
|
||||
sem_decl=e->decls->insertDecl( ident,sem_type,DECL_ARRAY );
|
||||
e->types.push_back( sem_type );
|
||||
sem_type = a; sem_decl = 0;
|
||||
} else {
|
||||
if (e->level > 0) ex("Array not found in main program");
|
||||
if (!t) t = Type::int_type;
|
||||
sem_type = d_new ArrayType(t, exprs->size());
|
||||
sem_decl = e->decls->insertDecl(ident, sem_type, DECL_ARRAY);
|
||||
e->types.push_back(sem_type);
|
||||
}
|
||||
exprs->semant( e );
|
||||
exprs->castTo( Type::int_type,e );
|
||||
exprs->semant(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 ){
|
||||
t=add( global( "_a"+ident ),iconst( k*4+12 ) );
|
||||
t=move( exprs->exprs[k]->translate(g),mem( t ) );
|
||||
g->code( t );
|
||||
g->code(call("__bbUndimArray", global("_a" + ident)));
|
||||
for (int k = 0; k < exprs->size(); ++k) {
|
||||
t = add(global("_a" + ident), iconst(k * 4 + 12));
|
||||
t = move(exprs->exprs[k]->translate(g), mem(t));
|
||||
g->code(t);
|
||||
}
|
||||
g->code( call( "__bbDimArray",global( "_a"+ident ) ) );
|
||||
g->code(call("__bbDimArray", global("_a" + ident)));
|
||||
|
||||
if( !sem_decl ) return;
|
||||
if (!sem_decl) return;
|
||||
|
||||
int et;
|
||||
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;
|
||||
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;
|
||||
|
||||
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 );
|
||||
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);
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Assignment //
|
||||
////////////////
|
||||
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" );
|
||||
expr=expr->semant( e );
|
||||
expr=expr->castTo( var->sem_type,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");
|
||||
expr = expr->semant(e);
|
||||
expr = expr->castTo(var->sem_type, e);
|
||||
}
|
||||
|
||||
void AssNode::translate( Codegen *g ){
|
||||
g->code( var->store( g,expr->translate( g ) ) );
|
||||
void AssNode::translate(Codegen *g) {
|
||||
g->code(var->store(g, expr->translate(g)));
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// Expression statement //
|
||||
//////////////////////////
|
||||
void ExprStmtNode::semant( Environ *e ){
|
||||
expr=expr->semant( e );
|
||||
void ExprStmtNode::semant(Environ *e) {
|
||||
expr = expr->semant(e);
|
||||
}
|
||||
|
||||
void ExprStmtNode::translate( Codegen *g ){
|
||||
TNode *t=expr->translate( g );
|
||||
if( expr->sem_type==Type::string_type ) t=call( "__bbStrRelease",t );
|
||||
g->code( t );
|
||||
void ExprStmtNode::translate(Codegen *g) {
|
||||
TNode *t = expr->translate(g);
|
||||
if (expr->sem_type == Type::string_type) t = call("__bbStrRelease", t);
|
||||
g->code(t);
|
||||
}
|
||||
|
||||
////////////////
|
||||
// user label //
|
||||
////////////////
|
||||
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 );
|
||||
ident=e->funcLabel+ident;
|
||||
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);
|
||||
ident = e->funcLabel + ident;
|
||||
}
|
||||
|
||||
void LabelNode::translate( Codegen *g ){
|
||||
g->label( "_l"+ident );
|
||||
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;
|
||||
else{
|
||||
sem_label=e->findLabel( ident );
|
||||
if( !sem_label ) sem_label=e->insertLabel( ident,-1,pos,-1 );
|
||||
if (ident.size() == 0) sem_label = 0;
|
||||
else {
|
||||
sem_label = e->findLabel(ident);
|
||||
if (!sem_label) sem_label = e->insertLabel(ident, -1, pos, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreNode::translate( Codegen *g ){
|
||||
TNode *t=global( "__DATA" );
|
||||
if( sem_label ) t=add( t,iconst( sem_label->data_sz*8 ) );
|
||||
g->code( call( "__bbRestore",t ) );
|
||||
void RestoreNode::translate(Codegen *g) {
|
||||
TNode *t = global("__DATA");
|
||||
if (sem_label) t = add(t, iconst(sem_label->data_sz * 8));
|
||||
g->code(call("__bbRestore", t));
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// Goto statement //
|
||||
////////////////////
|
||||
void GotoNode::semant( Environ *e ){
|
||||
if( !e->findLabel( ident ) ){
|
||||
e->insertLabel( ident,-1,pos,-1 );
|
||||
void GotoNode::semant(Environ *e) {
|
||||
if (!e->findLabel(ident)) {
|
||||
e->insertLabel(ident, -1, pos, -1);
|
||||
}
|
||||
ident=e->funcLabel+ident;
|
||||
ident = e->funcLabel + ident;
|
||||
}
|
||||
|
||||
void GotoNode::translate( Codegen *g ){
|
||||
g->code( jump( "_l"+ident ) );
|
||||
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 );
|
||||
ident=e->funcLabel+ident;
|
||||
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 ){
|
||||
g->code( jsr( "_l"+ident ) );
|
||||
void GosubNode::translate(Codegen *g) {
|
||||
g->code(jsr("_l" + ident));
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// If statement //
|
||||
//////////////////
|
||||
void IfNode::semant( Environ *e ){
|
||||
expr=expr->semant( e );
|
||||
expr=expr->castTo( Type::int_type,e );
|
||||
stmts->semant( e );
|
||||
if( elseOpt ) elseOpt->semant( 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);
|
||||
}
|
||||
|
||||
void IfNode::translate( Codegen *g ){
|
||||
if( ConstNode *c=expr->constNode() ){
|
||||
if( c->intValue() ) stmts->translate( g );
|
||||
else if( elseOpt ) elseOpt->translate( g );
|
||||
}else{
|
||||
string _else=genLabel();
|
||||
g->code( jumpf( expr->translate( g ),_else ) );
|
||||
stmts->translate( g );
|
||||
if( elseOpt ){
|
||||
string _else2=genLabel();
|
||||
g->code( jump( _else2 ) );
|
||||
g->label( _else );
|
||||
elseOpt->translate( g );
|
||||
_else=_else2;
|
||||
void IfNode::translate(Codegen *g) {
|
||||
if (ConstNode *c = expr->constNode()) {
|
||||
if (c->intValue()) stmts->translate(g);
|
||||
else if (elseOpt) elseOpt->translate(g);
|
||||
} else {
|
||||
string _else = genLabel();
|
||||
g->code(jumpf(expr->translate(g), _else));
|
||||
stmts->translate(g);
|
||||
if (elseOpt) {
|
||||
string _else2 = genLabel();
|
||||
g->code(jump(_else2));
|
||||
g->label(_else);
|
||||
elseOpt->translate(g);
|
||||
_else = _else2;
|
||||
}
|
||||
g->label( _else );
|
||||
g->label(_else);
|
||||
}
|
||||
}
|
||||
|
||||
///////////
|
||||
// Break //
|
||||
///////////
|
||||
void ExitNode::semant( Environ *e ){
|
||||
sem_brk=e->breakLabel;
|
||||
if( !sem_brk.size() ) ex( "break must appear inside a loop" );
|
||||
void ExitNode::semant(Environ *e) {
|
||||
sem_brk = e->breakLabel;
|
||||
if (!sem_brk.size()) ex("break must appear inside a loop");
|
||||
}
|
||||
|
||||
void ExitNode::translate( Codegen *g ){
|
||||
g->code( d_new TNode( IR_JUMP,0,0,sem_brk ) );
|
||||
void ExitNode::translate(Codegen *g) {
|
||||
g->code(d_new TNode(IR_JUMP, 0, 0, sem_brk));
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// While statement //
|
||||
/////////////////////
|
||||
void WhileNode::semant( Environ *e ){
|
||||
expr=expr->semant( e );
|
||||
expr=expr->castTo( Type::int_type,e );
|
||||
string brk=e->setBreak( sem_brk=genLabel() );
|
||||
stmts->semant( e );
|
||||
e->setBreak( brk );
|
||||
void WhileNode::semant(Environ *e) {
|
||||
expr = expr->semant(e);
|
||||
expr = expr->castTo(Type::int_type, e);
|
||||
string brk = e->setBreak(sem_brk = genLabel());
|
||||
stmts->semant(e);
|
||||
e->setBreak(brk);
|
||||
}
|
||||
|
||||
void WhileNode::translate( Codegen *g ){
|
||||
string loop=genLabel();
|
||||
if( ConstNode *c=expr->constNode() ){
|
||||
if( !c->intValue() ) return;
|
||||
g->label( loop );
|
||||
stmts->translate( g );
|
||||
g->code( jump( loop ) );
|
||||
}else{
|
||||
string cond=genLabel();
|
||||
g->code( jump( cond ) );
|
||||
g->label( loop );
|
||||
stmts->translate( g );
|
||||
debug( wendPos,g );
|
||||
g->label( cond );
|
||||
g->code( jumpt( expr->translate( g ),loop ) );
|
||||
void WhileNode::translate(Codegen *g) {
|
||||
string loop = genLabel();
|
||||
if (ConstNode *c = expr->constNode()) {
|
||||
if (!c->intValue()) return;
|
||||
g->label(loop);
|
||||
stmts->translate(g);
|
||||
g->code(jump(loop));
|
||||
} else {
|
||||
string cond = genLabel();
|
||||
g->code(jump(cond));
|
||||
g->label(loop);
|
||||
stmts->translate(g);
|
||||
debug(wendPos, g);
|
||||
g->label(cond);
|
||||
g->code(jumpt(expr->translate(g), loop));
|
||||
}
|
||||
g->label( sem_brk );
|
||||
g->label(sem_brk);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// 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){
|
||||
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) {
|
||||
}
|
||||
|
||||
ForNode::~ForNode(){
|
||||
ForNode::~ForNode() {
|
||||
delete stmts;
|
||||
delete stepExpr;
|
||||
delete toExpr;
|
||||
@@ -305,282 +303,283 @@ ForNode::~ForNode(){
|
||||
delete var;
|
||||
}
|
||||
|
||||
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!=Type::int_type && ty!=Type::float_type ){
|
||||
ex( "index variable must be integer or real" );
|
||||
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 != Type::int_type && ty != Type::float_type) {
|
||||
ex("index variable must be integer or real");
|
||||
}
|
||||
fromExpr=fromExpr->semant( e );
|
||||
fromExpr=fromExpr->castTo( ty,e );
|
||||
toExpr=toExpr->semant( e );
|
||||
toExpr=toExpr->castTo( ty,e );
|
||||
stepExpr=stepExpr->semant( e );
|
||||
stepExpr=stepExpr->castTo( ty,e );
|
||||
fromExpr = fromExpr->semant(e);
|
||||
fromExpr = fromExpr->castTo(ty, e);
|
||||
toExpr = toExpr->semant(e);
|
||||
toExpr = toExpr->castTo(ty, 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 );
|
||||
string brk = e->setBreak(sem_brk = genLabel());
|
||||
stmts->semant(e);
|
||||
e->setBreak(brk);
|
||||
}
|
||||
|
||||
void ForNode::translate( Codegen *g ){
|
||||
void ForNode::translate(Codegen *g) {
|
||||
|
||||
TNode *t;Type *ty=var->sem_type;
|
||||
TNode *t; Type *ty = var->sem_type;
|
||||
|
||||
//initial assignment
|
||||
g->code( var->store( g,fromExpr->translate( g ) ) );
|
||||
g->code(var->store(g, fromExpr->translate(g)));
|
||||
|
||||
string cond=genLabel();
|
||||
string loop=genLabel();
|
||||
g->code( jump( cond ) );
|
||||
g->label( loop );
|
||||
stmts->translate( g );
|
||||
string cond = genLabel();
|
||||
string loop = genLabel();
|
||||
g->code(jump(cond));
|
||||
g->label(loop);
|
||||
stmts->translate(g);
|
||||
|
||||
//execute the step part
|
||||
debug( nextPos,g );
|
||||
int op=ty==Type::int_type ? IR_ADD : IR_FADD;
|
||||
t=d_new TNode( op,var->load( g ),stepExpr->translate( g ) );
|
||||
g->code( var->store( g,t ) );
|
||||
debug(nextPos, g);
|
||||
int op = ty == Type::int_type ? IR_ADD : IR_FADD;
|
||||
t = d_new TNode(op, var->load(g), stepExpr->translate(g));
|
||||
g->code(var->store(g, t));
|
||||
|
||||
//test for loop cond
|
||||
g->label( cond );
|
||||
op=stepExpr->constNode()->floatValue()>0 ? '>' : '<';
|
||||
t=compare( op,var->load( g ),toExpr->translate( g ),ty );
|
||||
g->code( jumpf( t,loop ) );
|
||||
g->label(cond);
|
||||
op = stepExpr->constNode()->floatValue() > 0 ? '>' : '<';
|
||||
t = compare(op, var->load(g), toExpr->translate(g), ty);
|
||||
g->code(jumpf(t, loop));
|
||||
|
||||
g->label( sem_brk );
|
||||
g->label(sem_brk);
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
// For each object of a type //
|
||||
///////////////////////////////
|
||||
void ForEachNode::semant( Environ *e ){
|
||||
var->semant( e );
|
||||
Type *ty=var->sem_type;
|
||||
void ForEachNode::semant(Environ *e) {
|
||||
var->semant(e);
|
||||
Type *ty = var->sem_type;
|
||||
|
||||
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 (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");
|
||||
|
||||
string brk=e->setBreak( sem_brk=genLabel() );
|
||||
stmts->semant( e );
|
||||
e->setBreak( brk );
|
||||
string brk = e->setBreak(sem_brk = genLabel());
|
||||
stmts->semant(e);
|
||||
e->setBreak(brk);
|
||||
}
|
||||
|
||||
void ForEachNode::translate( Codegen *g ){
|
||||
TNode *t,*l,*r;
|
||||
string _loop=genLabel();
|
||||
void ForEachNode::translate(Codegen *g) {
|
||||
TNode *t, *l, *r;
|
||||
string _loop = genLabel();
|
||||
|
||||
string objFirst,objNext;
|
||||
string objFirst, objNext;
|
||||
|
||||
if( var->isObjParam() ){
|
||||
objFirst="__bbObjEachFirst2";
|
||||
objNext="__bbObjEachNext2";
|
||||
}else{
|
||||
objFirst="__bbObjEachFirst";
|
||||
objNext="__bbObjEachNext";
|
||||
if (var->isObjParam()) {
|
||||
objFirst = "__bbObjEachFirst2";
|
||||
objNext = "__bbObjEachNext2";
|
||||
} else {
|
||||
objFirst = "__bbObjEachFirst";
|
||||
objNext = "__bbObjEachNext";
|
||||
}
|
||||
|
||||
l=var->translate( g );
|
||||
r=global( "_t"+typeIdent );
|
||||
t=jumpf( call( objFirst,l,r ),sem_brk );
|
||||
g->code( t );
|
||||
l = var->translate(g);
|
||||
r = global("_t" + typeIdent);
|
||||
t = jumpf(call(objFirst, l, r), sem_brk);
|
||||
g->code(t);
|
||||
|
||||
g->label( _loop );
|
||||
stmts->translate( g );
|
||||
g->label(_loop);
|
||||
stmts->translate(g);
|
||||
|
||||
debug( nextPos,g );
|
||||
t=jumpt( call( objNext,var->translate( g ) ),_loop );
|
||||
g->code( t );
|
||||
debug(nextPos, g);
|
||||
t = jumpt(call(objNext, var->translate(g)), _loop);
|
||||
g->code(t);
|
||||
|
||||
g->label( sem_brk );
|
||||
g->label(sem_brk);
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// Return from a function //
|
||||
////////////////////////////
|
||||
void ReturnNode::semant( Environ *e ){
|
||||
if( e->level<=0 && expr ){
|
||||
ex( "Main program cannot return a value" );
|
||||
void ReturnNode::semant(Environ *e) {
|
||||
if (e->level <= 0 && expr) {
|
||||
ex("Main program cannot return a value");
|
||||
}
|
||||
if( e->level>0 ){
|
||||
if( !expr ){
|
||||
if( e->returnType==Type::float_type ){
|
||||
expr=d_new FloatConstNode( 0 );
|
||||
}else if( e->returnType==Type::string_type ){
|
||||
expr=d_new StringConstNode( "" );
|
||||
}else if( e->returnType->structType() ){
|
||||
expr=d_new NullNode();
|
||||
}else{
|
||||
expr=d_new IntConstNode( 0 );
|
||||
if (e->level > 0) {
|
||||
if (!expr) {
|
||||
if (e->returnType == Type::float_type) {
|
||||
expr = d_new FloatConstNode(0);
|
||||
} else if (e->returnType == Type::string_type) {
|
||||
expr = d_new StringConstNode("");
|
||||
} else if (e->returnType->structType()) {
|
||||
expr = d_new NullNode();
|
||||
} else {
|
||||
expr = d_new IntConstNode(0);
|
||||
}
|
||||
}
|
||||
expr=expr->semant( e );
|
||||
expr=expr->castTo( e->returnType,e );
|
||||
returnLabel=e->funcLabel+"_leave";
|
||||
expr = expr->semant(e);
|
||||
expr = expr->castTo(e->returnType, e);
|
||||
returnLabel = e->funcLabel + "_leave";
|
||||
}
|
||||
}
|
||||
|
||||
void ReturnNode::translate( Codegen *g ){
|
||||
if( !expr ){
|
||||
g->code( d_new TNode( IR_RET,0,0 ) );
|
||||
void ReturnNode::translate(Codegen *g) {
|
||||
if (!expr) {
|
||||
g->code(d_new TNode(IR_RET, 0, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
TNode *t=expr->translate( g );
|
||||
TNode *t = expr->translate(g);
|
||||
|
||||
if( expr->sem_type==Type::float_type ){
|
||||
g->code( d_new TNode( IR_FRETURN,t,0,returnLabel ) );
|
||||
}else{
|
||||
g->code( d_new TNode( IR_RETURN,t,0,returnLabel ) );
|
||||
if (expr->sem_type == Type::float_type) {
|
||||
g->code(d_new TNode(IR_FRETURN, t, 0, returnLabel));
|
||||
} else {
|
||||
g->code(d_new TNode(IR_RETURN, t, 0, returnLabel));
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// Delete statement //
|
||||
//////////////////////
|
||||
void DeleteNode::semant( Environ *e ){
|
||||
expr=expr->semant( e );
|
||||
if( expr->sem_type->structType()==0 ) ex( "Can't delete non-Newtype" );
|
||||
void DeleteNode::semant(Environ *e) {
|
||||
expr = expr->semant(e);
|
||||
if (expr->sem_type->structType() == 0) ex("Can't delete non-Newtype");
|
||||
}
|
||||
|
||||
void DeleteNode::translate( Codegen *g ){
|
||||
TNode *t=expr->translate( g );
|
||||
g->code( call( "__bbObjDelete",t ) );
|
||||
void DeleteNode::translate(Codegen *g) {
|
||||
TNode *t = expr->translate(g);
|
||||
g->code(call("__bbObjDelete", t));
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// Delete each of a type //
|
||||
///////////////////////////
|
||||
void DeleteEachNode::semant( Environ *e ){
|
||||
Type *t=e->findType( typeIdent );
|
||||
if( !t || t->structType()==0 ) ex( "Specified name is not a NewType name" );
|
||||
void DeleteEachNode::semant(Environ *e) {
|
||||
Type *t = e->findType(typeIdent);
|
||||
if (!t || t->structType() == 0) ex("Specified name is not a NewType name");
|
||||
}
|
||||
|
||||
void DeleteEachNode::translate( Codegen *g ){
|
||||
g->code( call( "__bbObjDeleteEach",global( "_t"+typeIdent ) ) );
|
||||
void DeleteEachNode::translate(Codegen *g) {
|
||||
g->code(call("__bbObjDeleteEach", global("_t" + typeIdent)));
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// Insert object in list //
|
||||
///////////////////////////
|
||||
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" );
|
||||
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");
|
||||
}
|
||||
|
||||
void InsertNode::translate( Codegen *g ){
|
||||
TNode *t1=expr1->translate( g );
|
||||
if( g->debug ) t1=jumpf( t1,"__bbNullObjEx" );
|
||||
TNode *t2=expr2->translate( g );
|
||||
if( g->debug ) t2=jumpf( t2,"__bbNullObjEx" );
|
||||
string s=before ? "__bbObjInsBefore" : "__bbObjInsAfter";
|
||||
g->code( call( s,t1,t2 ) );
|
||||
void InsertNode::translate(Codegen *g) {
|
||||
TNode *t1 = expr1->translate(g);
|
||||
if (g->debug) t1 = jumpf(t1, "__bbNullObjEx");
|
||||
TNode *t2 = expr2->translate(g);
|
||||
if (g->debug) t2 = jumpf(t2, "__bbNullObjEx");
|
||||
string s = before ? "__bbObjInsBefore" : "__bbObjInsAfter";
|
||||
g->code(call(s, t1, t2));
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
// A select statement //
|
||||
////////////////////////
|
||||
void SelectNode::semant( Environ *e ){
|
||||
expr=expr->semant( e );
|
||||
Type *ty=expr->sem_type;
|
||||
if( ty->structType() ) ex( "Select cannot be used with objects" );
|
||||
void SelectNode::semant(Environ *e) {
|
||||
expr = expr->semant(e);
|
||||
Type *ty = expr->sem_type;
|
||||
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 );
|
||||
sem_temp=d_new DeclVarNode( d );
|
||||
Decl *d = e->decls->insertDecl(genLabel(), expr->sem_type, DECL_LOCAL);
|
||||
sem_temp = d_new DeclVarNode(d);
|
||||
|
||||
for( int k=0;k<cases.size();++k ){
|
||||
CaseNode *c=cases[k];
|
||||
c->exprs->semant( e );
|
||||
c->exprs->castTo( ty,e );
|
||||
c->stmts->semant( e );
|
||||
for (int k = 0; k < cases.size(); ++k) {
|
||||
CaseNode *c = cases[k];
|
||||
c->exprs->semant(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;
|
||||
Type *ty = expr->sem_type;
|
||||
int k;
|
||||
|
||||
g->code( sem_temp->store( g,expr->translate( g ) ) );
|
||||
g->code(sem_temp->store(g, expr->translate(g)));
|
||||
|
||||
vector<string> labs;
|
||||
string brk=genLabel();
|
||||
string brk = genLabel();
|
||||
|
||||
for( int k=0;k<cases.size();++k ){
|
||||
CaseNode *c=cases[k];
|
||||
labs.push_back( genLabel() );
|
||||
for( int j=0;j<c->exprs->size();++j ){
|
||||
ExprNode *e=c->exprs->exprs[j];
|
||||
TNode *t=compare( '=',sem_temp->load( g ),e->translate( g ),ty );
|
||||
g->code( jumpt( t,labs.back() ) );
|
||||
for (k = 0; k < cases.size(); ++k) {
|
||||
CaseNode *c = cases[k];
|
||||
labs.push_back(genLabel());
|
||||
for (int j = 0; j < c->exprs->size(); ++j) {
|
||||
ExprNode *e = c->exprs->exprs[j];
|
||||
TNode *t = compare('=', sem_temp->load(g), e->translate(g), ty);
|
||||
g->code(jumpt(t, labs.back()));
|
||||
}
|
||||
}
|
||||
if( defStmts ) defStmts->translate( g );
|
||||
g->code( jump( brk ) );
|
||||
for( k=0;k<cases.size();++k ){
|
||||
CaseNode *c=cases[k];
|
||||
g->label( labs[k] );
|
||||
c->stmts->translate( g );
|
||||
g->code( jump( brk ) );
|
||||
if (defStmts) defStmts->translate(g);
|
||||
g->code(jump(brk));
|
||||
for (k = 0; k < cases.size(); ++k) {
|
||||
CaseNode *c = cases[k];
|
||||
g->label(labs[k]);
|
||||
c->stmts->translate(g);
|
||||
g->code(jump(brk));
|
||||
}
|
||||
|
||||
g->label( brk );
|
||||
g->label(brk);
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// Repeat...Until/Forever //
|
||||
////////////////////////////
|
||||
void RepeatNode::semant( Environ *e ){
|
||||
sem_brk=genLabel();
|
||||
string brk=e->setBreak( sem_brk );
|
||||
stmts->semant( e );
|
||||
e->setBreak( brk );
|
||||
if( expr ){
|
||||
expr=expr->semant( e );
|
||||
expr=expr->castTo( Type::int_type,e );
|
||||
void RepeatNode::semant(Environ *e) {
|
||||
sem_brk = genLabel();
|
||||
string brk = e->setBreak(sem_brk);
|
||||
stmts->semant(e);
|
||||
e->setBreak(brk);
|
||||
if (expr) {
|
||||
expr = expr->semant(e);
|
||||
expr = expr->castTo(Type::int_type, e);
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatNode::translate( Codegen *g ){
|
||||
void RepeatNode::translate(Codegen *g) {
|
||||
|
||||
string loop=genLabel();
|
||||
g->label( loop );
|
||||
stmts->translate( g );
|
||||
debug( untilPos,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 ) );
|
||||
}else{
|
||||
if( expr ) g->code( jumpf( expr->translate( g ),loop ) );
|
||||
else g->code( jump( loop ) );
|
||||
if (ConstNode *c = expr ? expr->constNode() : 0) {
|
||||
if (!c->intValue()) g->code(jump(loop));
|
||||
} else {
|
||||
if (expr) g->code(jumpf(expr->translate(g), loop));
|
||||
else g->code(jump(loop));
|
||||
}
|
||||
g->label( sem_brk );
|
||||
g->label(sem_brk);
|
||||
}
|
||||
|
||||
///////////////
|
||||
// Read data //
|
||||
///////////////
|
||||
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" );
|
||||
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");
|
||||
}
|
||||
|
||||
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" );
|
||||
g->code( var->store( g,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");
|
||||
g->code(var->store(g, t));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user