compiler: Move and modernize

compiler is blitzcc, what I previously called compiler is now compiler_lib
This commit is contained in:
Michael Fabian 'Xaymar' Dirks
2019-01-19 18:28:07 +01:00
parent d7fc9de5e2
commit c4947bd12a
79 changed files with 6544 additions and 4853 deletions
+33 -37
View File
@@ -1,45 +1,24 @@
project(compiler) project(compiler)
add_library(${PROJECT_NAME} MODULE add_subdirectory(lib)
"assem.hpp" add_subdirectory(gen)
"codegen.hpp"
"compiler.cpp" set(PRIVATE_SOURCE
"compiler.hpp" "main.cpp"
"decl.cpp" "libs.cpp"
"decl.hpp" "libs.hpp"
"declnode.cpp"
"declnode.hpp"
"environ.cpp"
"environ.hpp"
"ex.hpp"
"exprnode.cpp"
"exprnode.hpp"
"label.hpp"
"node.cpp"
"node.hpp"
"nodes.hpp"
"parser.cpp"
"parser.hpp"
"prognode.cpp"
"prognode.hpp"
"std.cpp"
"std.hpp"
"stmtnode.cpp"
"stmtnode.hpp"
"stringmap.hpp"
"toker.cpp"
"toker.hpp"
"type.cpp"
"type.hpp"
"var.hpp"
"varnode.cpp"
"varnode.hpp"
) )
add_executable(${PROJECT_NAME}
${PRIVATE_SOURCE}
)
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "blitzcc")
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}
PRIVATE compiler_lib
config linker
stdutil runtime
) )
target_include_directories(${PROJECT_NAME} target_include_directories(${PROJECT_NAME}
@@ -96,3 +75,20 @@ if (WIN32)
NOINOUT NOINOUT
) )
endif() endif()
install(TARGETS ${PROJECT_NAME} runtime linker
DESTINATION lib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
OBJECTS DESTINATION lib
RESOURCE DESTINATION lib
PUBLIC_HEADER DESTINATION include
PRIVATE_HEADER DESTINATION source
)
if(MSVC)
install(
FILES $<TARGET_PDB_FILE:${PROJECT_NAME}> ${fmod_BINARIES} ${FreeImage_BINARIES}
DESTINATION bin
OPTIONAL
)
endif()
-15
View File
@@ -1,15 +0,0 @@
#ifndef ASSEM_H
#define ASSEM_H
#include "..\LinkerLib\linker.hpp"
class Assem {
public:
istream& in;
Module* mod;
Assem(istream& in, Module* mod) : in(in), mod(mod) {}
virtual void assemble() = 0;
};
#endif
File diff suppressed because it is too large Load Diff
-37
View File
@@ -1,37 +0,0 @@
#ifndef ASSEM_X86_H
#define ASSEM_X86_H
#include "../assem.h"
#include <string>
#include <vector>
#include <iostream>
#include "insts.h"
#include "operand.h"
using namespace std;
class Assem_x86 : public Assem{
public:
Assem_x86( istream &in,Module *mod );
virtual void assemble();
private:
void align( int n );
void emit( int n );
void emitw( int n );
void emitd( int n );
void emitImm( const string &s,int size );
void emitImm( const Operand &o,int size );
void r_reloc( const string &dest );
void a_reloc( const string &dest );
void assemDir( const string &name,const string &op );
void assemInst( const string &name,const string &lhs,const string &rhs );
void assemLine( const string &line );
};
#endif
-32
View File
@@ -1,32 +0,0 @@
#ifndef OPERAND_H
#define OPERAND_H
#include <string>
#include <iostream>
using namespace std;
struct Operand{
int mode;
int reg,imm,offset;
string immLabel,baseLabel;
int baseReg,indexReg,shift;
Operand();
Operand( const string &s );
void parse();
private:
string s;
bool parseSize( int *sz );
bool parseChar( char c );
bool parseReg( int *reg );
bool parseFPReg( int *reg );
bool parseLabel( string *t );
bool parseConst( int *iconst );
};
#endif
-29
View File
@@ -1,29 +0,0 @@
/*
A block represents a function - code & data.
*/
#ifndef BLOCK_H
#define BLOCK_H
struct Block{
Block( Block *parent );
~Block();
void genCode( TNode *t ){ code.push_back( t ); }
void genData( TNode *t ){ data.push_back( t ); }
void generate( Codegen *gen );
private:
Block *parent;
vector<Block*> children;
vector<TNode*> code;
vector<TNode*> data;
};
#endif
-38
View File
@@ -1,38 +0,0 @@
#include "../codegen.h"
struct Tile;
class Codegen_x86 : public Codegen{
public:
Codegen_x86( ostream &out,bool debug );
virtual void enter( const string &l,int frameSize );
virtual void code( TNode *code );
virtual void leave( TNode *cleanup,int pop_sz );
virtual void label( const string &l );
virtual void i_data( int i,const string &l );
virtual void s_data( const string &s,const string &l );
virtual void p_data( const string &p,const string &l );
virtual void align_data( int n );
virtual void flush();
private:
bool inCode;
Tile *genCompare( TNode *t,string &func,bool negate );
Tile *munch( TNode *t ); //munch and discard result
Tile *munchReg( TNode *t ); //munch and put result in a CPU reg
Tile *munchFP( TNode *t ); //munch and put result on FP stack
Tile *munchCall( TNode *t );
Tile *munchUnary( TNode *t );
Tile *munchLogical( TNode *t );
Tile *munchArith( TNode *t );
Tile *munchShift( TNode *t );
Tile *munchRelop( TNode *t );
Tile *munchFPUnary( TNode *t );
Tile *munchFPArith( TNode *t );
Tile *munchFPRelop( TNode *t );
};
-25
View File
@@ -1,25 +0,0 @@
#ifndef TILE_H
#define TILE_H
enum{ EAX=1,ECX,EDX,EDI,ESI,EBX };
struct Tile{
int want_l,want_r,hits,argFrame;
Tile( const string &a,Tile *l=0,Tile *r=0 );
Tile( const string &a,const string &a2,Tile *l=0,Tile *r=0 );
~Tile();
void label();
int eval( int want );
private:
int need;
Tile *l,*r;
string assem,assem2;
};
#endif
View File
View File
-41
View File
@@ -1,41 +0,0 @@
#ifndef DECL_H
#define DECL_H
enum {
DECL_FUNC = 1,
DECL_ARRAY = 2,
DECL_STRUCT = 4, //NOT vars
DECL_GLOBAL = 8,
DECL_LOCAL = 16,
DECL_PARAM = 32,
DECL_FIELD = 64 //ARE vars
};
struct Type;
struct ConstType;
struct Decl {
string name;
Type* type; //type
int kind, offset;
ConstType* defType; //default value
Decl(const string& s, Type* t, int k, ConstType* d = 0) : name(s), type(t), kind(k), defType(d) {}
~Decl();
virtual void getName(char* buff);
};
struct DeclSeq {
vector<Decl*> decls;
DeclSeq();
~DeclSeq();
Decl* findDecl(const string& s);
Decl* insertDecl(const string& s, Type* t, int kind, ConstType* d = 0);
int size()
{
return decls.size();
}
};
#endif
-16
View File
@@ -1,16 +0,0 @@
#ifndef DECL_H
#define DECL_H
#include "type.h"
const int OFFSET_GLOBAL=0x80000000;
struct Decl{
int offset;
Type *type;
Decl( int n,Type *t ):offset(n),type(t){}
virtual Decl *Decl(){ return 0; }
};
#endif
-122
View File
@@ -1,122 +0,0 @@
#ifndef DECLNODE_H
#define DECLNODE_H
struct DeclNode : public Node {
int pos;
string file;
DeclNode() : pos(-1) {}
virtual void proto(DeclSeq* d, Environ* e) {}
virtual void semant(Environ* e) {}
virtual void translate(Codegen* g) {}
virtual void transdata(Codegen* g) {}
};
struct DeclSeqNode : public Node {
vector<DeclNode*> decls;
DeclSeqNode() {}
~DeclSeqNode()
{
for (; decls.size(); decls.pop_back())
delete decls.back();
}
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
void transdata(Codegen* g);
void push_back(DeclNode* d)
{
decls.push_back(d);
}
int size()
{
return decls.size();
}
};
#include "exprnode.hpp"
#include "stmtnode.hpp"
//'kind' shouldn't really be in Parser...
//should probably be LocalDeclNode,GlobalDeclNode,ParamDeclNode
struct VarDeclNode : public DeclNode {
string ident, tag;
int kind;
bool constant;
ExprNode* expr;
DeclVarNode* sem_var;
VarDeclNode(const string& i, const string& t, int k, bool c, ExprNode* e)
: ident(i), tag(t), kind(k), constant(c), expr(e), sem_var(0)
{}
~VarDeclNode()
{
delete expr;
delete sem_var;
}
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
};
struct FuncDeclNode : public DeclNode {
string ident, tag;
DeclSeqNode* params;
StmtSeqNode* stmts;
FuncType* sem_type;
Environ* sem_env;
FuncDeclNode(const string& i, const string& t, DeclSeqNode* p, StmtSeqNode* ss)
: ident(i), tag(t), params(p), stmts(ss)
{}
~FuncDeclNode()
{
delete params;
delete stmts;
}
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
};
struct StructDeclNode : public DeclNode {
string ident;
DeclSeqNode* fields;
StructType* sem_type;
StructDeclNode(const string& i, DeclSeqNode* f) : ident(i), fields(f) {}
~StructDeclNode()
{
delete fields;
}
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
};
struct DataDeclNode : public DeclNode {
ExprNode* expr;
string str_label;
DataDeclNode(ExprNode* e) : expr(e) {}
~DataDeclNode()
{
delete expr;
}
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
void transdata(Codegen* g);
};
struct VectorDeclNode : public DeclNode {
string ident, tag;
ExprSeqNode* exprs;
int kind;
VectorType* sem_type;
VectorDeclNode(const string& i, const string& t, ExprSeqNode* e, int k) : ident(i), tag(t), exprs(e), kind(k) {}
~VectorDeclNode()
{
delete exprs;
}
void proto(DeclSeq* d, Environ* e);
void translate(Codegen* g);
};
#endif
-42
View File
@@ -1,42 +0,0 @@
/*
An environ represent a stack frame block.
*/
#ifndef ENVIRON_H
#define ENVIRON_H
#include "decl.hpp"
#include "label.hpp"
#include "type.hpp"
class Environ {
public:
int level;
DeclSeq* decls;
DeclSeq* funcDecls;
DeclSeq* typeDecls;
vector<Type*> types;
vector<Label*> labels;
Environ* globals;
Type* returnType;
string funcLabel, breakLabel;
list<Environ*> children; //for delete!
Environ(const string& f, Type* r, int l, Environ* gs);
~Environ();
Decl* findDecl(const string& s);
Decl* findFunc(const string& s);
Type* findType(const string& s);
Label* findLabel(const string& s);
Label* insertLabel(const string& s, int def, int src, int sz);
string setBreak(const string& s);
};
#endif
-13
View File
@@ -1,13 +0,0 @@
#ifndef EX_H
#define EX_H
struct Ex {
string ex; //what happened
int pos; //source offset
string file;
Ex(const string& ex) : ex(ex), pos(-1) {}
Ex(const string& ex, int pos, const string& t) : ex(ex), pos(pos), file(t) {}
};
#endif
+75
View File
@@ -0,0 +1,75 @@
project(compiler_gen)
set(PRIVATE_SOURCE
"main.cpp"
"nasm_insts.txt"
)
add_executable(${PROJECT_NAME}
${PRIVATE_SOURCE}
)
target_link_libraries(${PROJECT_NAME}
)
target_include_directories(${PROJECT_NAME}
PUBLIC
${PROJECT_SOURCE_DIR}
)
if (WIN32)
target_compile_definitions(${PROJECT_NAME}
PRIVATE
_CRT_SECURE_NO_WARNINGS
# windows.h
WIN32_LEAN_AND_MEAN
NOGPICAPMASKS
NOVIRTUALKEYCODES
NOWINMESSAGES
NOWINSTYLES
NOSYSMETRICS
NOMENUS
NOICONS
NOKEYSTATES
NOSYSCOMMANDS
NORASTEROPS
NOSHOWWINDOW
NOATOM
NOCLIPBOARD
NOCOLOR
NOCTLMGR
NODRAWTEXT
NOGDI
NOKERNEL
NOUSER
NONLS
NOMB
NOMEMMGR
NOMETAFILE
NOMINMAX
NOMSG
NOOPENFILE
NOSCROLL
NOSERVICE
NOSOUND
NOTEXTMETRIC
NOWH
NOWINOFFSETS
NOCOMM
NOKANJI
NOHELP
NOPROFILER
NODEFERWINDOWPOS
NOMCX
NOIME
NOMDI
NOINOUT
)
endif()
add_custom_command(TARGET ${PROJECT_NAME}
PRE_LINK
COMMAND ${CMAKE_COMMAND} -E copy
"${PROJECT_SOURCE_DIR}/nasm_insts.txt"
"$<TARGET_FILE_DIR:${PROJECT_NAME}>/nasm_insts.txt"
)
File diff suppressed because it is too large Load Diff
+194
View File
@@ -0,0 +1,194 @@
/*
This generates a source code file for x86 instruction formats.
Thanks NASM!
*/
#include <conio.h>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
static const char* optype(const string& s)
{
if (s == "AL")
return "AL";
if (s == "AX")
return "AX";
if (s == "EAX")
return "EAX";
if (s == "CL")
return "CL";
if (s == "CX")
return "CX";
if (s == "ECX")
return "ECX";
if (s == "imm")
return "IMM";
if (s == "imm8")
return "IMM8";
if (s == "imm16")
return "IMM16";
if (s == "imm32")
return "IMM32";
if (s == "reg")
return "REG";
if (s == "reg8")
return "REG8";
if (s == "reg16")
return "REG16";
if (s == "reg32")
return "REG32";
if (s == "mem")
return "MEM";
if (s == "mem8")
return "MEM8";
if (s == "mem16")
return "MEM16";
if (s == "mem32")
return "MEM32";
if (s == "r/m")
return "R_M";
if (s == "r/m8")
return "R_M8";
if (s == "r/m16")
return "R_M16";
if (s == "r/m32")
return "R_M32";
if (s == "fpureg")
return "FPUREG";
if (s == "ST0")
return "ST0";
return 0;
}
void __cdecl main()
{
string name, lhs, rhs, byte, bytes, flags, last;
ifstream in("nasm_insts.txt");
ofstream out("insts.cpp");
out << "//\n//This is generated code - do not modify!!!!!\n//\n";
out << "\n#include \"insts.hpp\"\n\n";
out << "Inst insts[]={\n";
for (; !in.eof(); in.ignore(INT_MAX, '\n')) {
name.resize(0);
in >> name;
if (!name.size() || name[0] == '/')
continue;
lhs.resize(0);
rhs.resize(0);
const char *lop = "NONE", *rop = "NONE";
while (isspace(in.peek()))
in.get();
getline(in, lhs, ';');
if (int i = lhs.size()) {
while (i && isspace(lhs[i - 1]))
--i;
if (i) {
lhs.resize(i);
i = lhs.find(',');
if (i != string::npos) {
rhs = lhs.substr(i + 1);
lhs = lhs.substr(0, i);
}
lop = optype(lhs);
if (!lop)
continue;
if (rhs.size() && !(rop = optype(rhs)))
continue;
}
}
bytes.resize(0);
flags = '0';
bool fail = false;
while (!fail) {
in >> byte;
if (byte[0] == '[')
break;
if (byte == "/r")
flags += "|_R";
else if (byte == "/0")
flags += "|_0";
else if (byte == "/1")
flags += "|_1";
else if (byte == "/2")
flags += "|_2";
else if (byte == "/3")
flags += "|_3";
else if (byte == "/4")
flags += "|_4";
else if (byte == "/5")
flags += "|_5";
else if (byte == "/6")
flags += "|_6";
else if (byte == "/7")
flags += "|_7";
else if (byte == "o16")
flags += "|O16";
else if (byte == "o32")
flags += "|O32";
else if (byte == "ow/od")
flags += "|OW_OD";
else if (byte == "ib")
flags += "|IB";
else if (byte == "iw")
flags += "|IW";
else if (byte == "id")
flags += "|ID";
else if (byte == "rw/rd")
flags += "|RW_RD";
else if (isxdigit(byte[0])) {
string sub = byte.substr(2);
if (sub.size()) {
if (sub == "+r")
flags += "|PLUSREG";
else if (sub == "+cc")
flags += "|PLUSCC";
else
fail = true;
}
bytes = bytes + "\\x" + byte[0] + byte[1];
} else
fail = true;
}
if (fail)
continue;
if (flags.find("0|") == 0)
flags = flags.substr(2);
for (size_t k = 0; k < name.size(); ++k)
name[k] = tolower(name[k]);
if (name == last)
name = "0";
else {
last = name;
name = '\"' + name + '\"';
}
char bf[4];
_itoa(bytes.size() / 3, bf, 16);
bytes = "\\x" + string(bf) + bytes;
out << name << ',' << lop << ',' << rop << ',' << flags << ",\"" << bytes << "\",\n";
}
out << "\"\",0,0,0,0\n};\n";
out.flush();
out.close();
cout << "All done!\n";
_getch();
}
+760
View File
@@ -0,0 +1,760 @@
AAA ; 37 [8086]
AAS ; 3F [8086]
AAD ; D5 0A [8086]
AAD imm ; D5 ib [8086]
AAM ; D4 0A [8086]
AAM imm ; D4 ib [8086]
ADC AL,imm8 ; 14 ib [8086]
ADC AX,imm16 ; o16 15 iw [8086]
ADC EAX,imm32 ; o32 15 id [386]
ADC r/m8,reg8 ; 10 /r [8086]
ADC r/m16,reg16 ; o16 11 /r [8086]
ADC r/m32,reg32 ; o32 11 /r [386]
ADC reg8,r/m8 ; 12 /r [8086]
ADC reg16,r/m16 ; o16 13 /r [8086]
ADC reg32,r/m32 ; o32 13 /r [386]
ADC r/m8,imm8 ; 80 /2 ib [8086]
ADC r/m16,imm16 ; o16 81 /2 iw [8086]
ADC r/m32,imm32 ; o32 81 /2 id [386]
ADC r/m16,imm8 ; o16 83 /2 ib [8086]
ADC r/m32,imm8 ; o32 83 /2 ib [386]
ADD AL,imm8 ; 04 ib [8086]
ADD AX,imm16 ; o16 05 iw [8086]
ADD EAX,imm32 ; o32 05 id [386]
ADD r/m8,reg8 ; 00 /r [8086]
ADD r/m16,reg16 ; o16 01 /r [8086]
ADD r/m32,reg32 ; o32 01 /r [386]
ADD reg8,r/m8 ; 02 /r [8086]
ADD reg16,r/m16 ; o16 03 /r [8086]
ADD reg32,r/m32 ; o32 03 /r [386]
ADD r/m8,imm8 ; 80 /0 ib [8086]
ADD r/m16,imm16 ; o16 81 /0 iw [8086]
ADD r/m32,imm32 ; o32 81 /0 id [386]
ADD r/m16,imm8 ; o16 83 /0 ib [8086]
ADD r/m32,imm8 ; o32 83 /0 ib [386]
AND AL,imm8 ; 24 ib [8086]
AND AX,imm16 ; o16 25 iw [8086]
AND EAX,imm32 ; o32 25 id [386]
AND r/m8,reg8 ; 20 /r [8086]
AND r/m16,reg16 ; o16 21 /r [8086]
AND r/m32,reg32 ; o32 21 /r [386]
AND reg8,r/m8 ; 22 /r [8086]
AND reg16,r/m16 ; o16 23 /r [8086]
AND reg32,r/m32 ; o32 23 /r [386]
AND r/m8,imm8 ; 80 /4 ib [8086]
AND r/m16,imm16 ; o16 81 /4 iw [8086]
AND r/m32,imm32 ; o32 81 /4 id [386]
AND r/m16,imm8 ; o16 83 /4 ib [8086]
AND r/m32,imm8 ; o32 83 /4 ib [386]
ARPL r/m16,reg16 ; 63 /r [286,PRIV]
BOUND reg16,mem ; o16 62 /r [186]
BOUND reg32,mem ; o32 62 /r [386]
BSF reg16,r/m16 ; o16 0F BC /r [386]
BSF reg32,r/m32 ; o32 0F BC /r [386]
BSR reg16,r/m16 ; o16 0F BD /r [386]
BSR reg32,r/m32 ; o32 0F BD /r [386]
BSWAP reg32 ; o32 0F C8+r [486]
BT r/m16,reg16 ; o16 0F A3 /r [386]
BT r/m32,reg32 ; o32 0F A3 /r [386]
BT r/m16,imm8 ; o16 0F BA /4 ib [386]
BT r/m32,imm8 ; o32 0F BA /4 ib [386]
BTC r/m16,reg16 ; o16 0F BB /r [386]
BTC r/m32,reg32 ; o32 0F BB /r [386]
BTC r/m16,imm8 ; o16 0F BA /7 ib [386]
BTC r/m32,imm8 ; o32 0F BA /7 ib [386]
BTR r/m16,reg16 ; o16 0F B3 /r [386]
BTR r/m32,reg32 ; o32 0F B3 /r [386]
BTR r/m16,imm8 ; o16 0F BA /6 ib [386]
BTR r/m32,imm8 ; o32 0F BA /6 ib [386]
BTS r/m16,reg16 ; o16 0F AB /r [386]
BTS r/m32,reg32 ; o32 0F AB /r [386]
BTS r/m16,imm ; o16 0F BA /5 ib [386]
BTS r/m32,imm ; o32 0F BA /5 ib [386]
CALL imm ; E8 rw/rd [8086]
//CALL imm:imm16 ; o16 9A iw iw [8086]
//CALL imm:imm32 ; o32 9A id iw [386]
//CALL FAR mem16 ; o16 FF /3 [8086]
//CALL FAR mem32 ; o32 FF /3 [386]
CALL r/m16 ; o16 FF /2 [8086]
CALL r/m32 ; o32 FF /2 [386]
CBW ; o16 98 [8086]
CWD ; o16 99 [8086]
CDQ ; o32 99 [386]
CWDE ; o32 98 [386]
CLC ; F8 [8086]
CLD ; FC [8086]
CLI ; FA [8086]
CLTS ; 0F 06 [286,PRIV]
CMC ; F5 [8086]
CMOVcc reg16,r/m16 ; o16 0F 40+cc /r [P6]
CMOVcc reg32,r/m32 ; o32 0F 40+cc /r [P6]
CMP AL,imm8 ; 3C ib [8086]
CMP AX,imm16 ; o16 3D iw [8086]
CMP EAX,imm32 ; o32 3D id [386]
CMP r/m8,reg8 ; 38 /r [8086]
CMP r/m16,reg16 ; o16 39 /r [8086]
CMP r/m32,reg32 ; o32 39 /r [386]
CMP reg8,r/m8 ; 3A /r [8086]
CMP reg16,r/m16 ; o16 3B /r [8086]
CMP reg32,r/m32 ; o32 3B /r [386]
CMP r/m8,imm8 ; 80 /7 ib [8086]
CMP r/m16,imm16 ; o16 81 /7 iw [8086]
CMP r/m32,imm32 ; o32 81 /7 id [386]
CMP r/m16,imm8 ; o16 83 /7 ib [8086]
CMP r/m32,imm8 ; o32 83 /7 ib [386]
CMPSB ; A6 [8086]
CMPSW ; o16 A7 [8086]
CMPSD ; o32 A7 [386]
CMPXCHG r/m8,reg8 ; 0F B0 /r [PENT]
CMPXCHG r/m16,reg16 ; o16 0F B1 /r [PENT]
CMPXCHG r/m32,reg32 ; o32 0F B1 /r [PENT]
CMPXCHG486 r/m8,reg8 ; 0F A6 /r [486,UNDOC]
CMPXCHG486 r/m16,reg16 ; o16 0F A7 /r [486,UNDOC]
CMPXCHG486 r/m32,reg32 ; o32 0F A7 /r [486,UNDOC]
CMPXCHG8B mem ; 0F C7 /1 [PENT]
CPUID ; 0F A2 [PENT]
DAA ; 27 [8086]
DAS ; 2F [8086]
DEC reg16 ; o16 48+r [8086]
DEC reg32 ; o32 48+r [386]
DEC r/m8 ; FE /1 [8086]
DEC r/m16 ; o16 FF /1 [8086]
DEC r/m32 ; o32 FF /1 [386]
DIV r/m8 ; F6 /6 [8086]
DIV r/m16 ; o16 F7 /6 [8086]
DIV r/m32 ; o32 F7 /6 [386]
EMMS ; 0F 77 [PENT,MMX]
ENTER imm,imm ; C8 iw ib [186]
F2XM1 ; D9 F0 [8086,FPU]
FABS ; D9 E1 [8086,FPU]
FADD mem32 ; D8 /0 [8086,FPU]
FADD mem64 ; DC /0 [8086,FPU]
FADD fpureg ; D8 C0+r [8086,FPU]
FADD ST0,fpureg ; D8 C0+r [8086,FPU]
FADD TO fpureg ; DC C0+r [8086,FPU]
FADD fpureg,ST0 ; DC C0+r [8086,FPU]
FADDP fpureg ; DE C0+r [8086,FPU]
FADDP fpureg,ST0 ; DE C0+r [8086,FPU]
FBLD mem80 ; DF /4 [8086,FPU]
FBSTP mem80 ; DF /6 [8086,FPU]
FCHS ; D9 E0 [8086,FPU]
FCLEX ; 9B DB E2 [8086,FPU]
FNCLEX ; DB E2 [8086,FPU]
FCMOVB fpureg ; DA C0+r [P6,FPU]
FCMOVB ST0,fpureg ; DA C0+r [P6,FPU]
FCMOVBE fpureg ; DA D0+r [P6,FPU]
FCMOVBE ST0,fpureg ; DA D0+r [P6,FPU]
FCMOVE fpureg ; DA C8+r [P6,FPU]
FCMOVE ST0,fpureg ; DA C8+r [P6,FPU]
FCMOVNB fpureg ; DB C0+r [P6,FPU]
FCMOVNB ST0,fpureg ; DB C0+r [P6,FPU]
FCMOVNBE fpureg ; DB D0+r [P6,FPU]
FCMOVNBE ST0,fpureg ; DB D0+r [P6,FPU]
FCMOVNE fpureg ; DB C8+r [P6,FPU]
FCMOVNE ST0,fpureg ; DB C8+r [P6,FPU]
FCMOVNU fpureg ; DB D8+r [P6,FPU]
FCMOVNU ST0,fpureg ; DB D8+r [P6,FPU]
FCMOVU fpureg ; DA D8+r [P6,FPU]
FCMOVU ST0,fpureg ; DA D8+r [P6,FPU]
FCOM mem32 ; D8 /2 [8086,FPU]
FCOM mem64 ; DC /2 [8086,FPU]
FCOM fpureg ; D8 D0+r [8086,FPU]
FCOM ST0,fpureg ; D8 D0+r [8086,FPU]
FCOMP mem32 ; D8 /3 [8086,FPU]
FCOMP mem64 ; DC /3 [8086,FPU]
FCOMP fpureg ; D8 D8+r [8086,FPU]
FCOMP ST0,fpureg ; D8 D8+r [8086,FPU]
FCOMPP ; DE D9 [8086,FPU]
FCOMI fpureg ; DB F0+r [P6,FPU]
FCOMI ST0,fpureg ; DB F0+r [P6,FPU]
FCOMIP fpureg ; DF F0+r [P6,FPU]
FCOMIP ST0,fpureg ; DF F0+r [P6,FPU]
FCOS ; D9 FF [386,FPU]
FDECSTP ; D9 F6 [8086,FPU]
FDISI ; 9B DB E1 [8086,FPU]
FNDISI ; DB E1 [8086,FPU]
FENI ; 9B DB E0 [8086,FPU]
FNENI ; DB E0 [8086,FPU]
FDIV mem32 ; D8 /6 [8086,FPU]
FDIV mem64 ; DC /6 [8086,FPU]
FDIV fpureg ; D8 F0+r [8086,FPU]
FDIV ST0,fpureg ; D8 F0+r [8086,FPU]
FDIV TO fpureg ; DC F8+r [8086,FPU]
FDIV fpureg,ST0 ; DC F8+r [8086,FPU]
FDIVR mem32 ; D8 /0 [8086,FPU]
FDIVR mem64 ; DC /0 [8086,FPU]
FDIVR fpureg ; D8 F8+r [8086,FPU]
FDIVR ST0,fpureg ; D8 F8+r [8086,FPU]
FDIVR TO fpureg ; DC F0+r [8086,FPU]
FDIVR fpureg,ST0 ; DC F0+r [8086,FPU]
FDIVP fpureg ; DE F8+r [8086,FPU]
FDIVP fpureg,ST0 ; DE F8+r [8086,FPU]
FDIVRP fpureg ; DE F0+r [8086,FPU]
FDIVRP fpureg,ST0 ; DE F0+r [8086,FPU]
FFREE fpureg ; DD C0+r [8086,FPU]
FIADD mem16 ; DE /0 [8086,FPU]
FIADD mem32 ; DA /0 [8086,FPU]
FICOM mem16 ; DE /2 [8086,FPU]
FICOM mem32 ; DA /2 [8086,FPU]
FICOMP mem16 ; DE /3 [8086,FPU]
FICOMP mem32 ; DA /3 [8086,FPU]
FIDIV mem16 ; DE /6 [8086,FPU]
FIDIV mem32 ; DA /6 [8086,FPU]
FIDIVR mem16 ; DE /0 [8086,FPU]
FIDIVR mem32 ; DA /0 [8086,FPU]
FILD mem16 ; DF /0 [8086,FPU]
FILD mem32 ; DB /0 [8086,FPU]
FILD mem64 ; DF /5 [8086,FPU]
FIST mem16 ; DF /2 [8086,FPU]
FIST mem32 ; DB /2 [8086,FPU]
FISTP mem16 ; DF /3 [8086,FPU]
FISTP mem32 ; DB /3 [8086,FPU]
FISTP mem64 ; DF /0 [8086,FPU]
FIMUL mem16 ; DE /1 [8086,FPU]
FIMUL mem32 ; DA /1 [8086,FPU]
FINCSTP ; D9 F7 [8086,FPU]
FINIT ; 9B DB E3 [8086,FPU]
FNINIT ; DB E3 [8086,FPU]
FISUB mem16 ; DE /4 [8086,FPU]
FISUB mem32 ; DA /4 [8086,FPU]
FISUBR mem16 ; DE /5 [8086,FPU]
FISUBR mem32 ; DA /5 [8086,FPU]
FLD mem32 ; D9 /0 [8086,FPU]
FLD mem64 ; DD /0 [8086,FPU]
FLD mem80 ; DB /5 [8086,FPU]
FLD fpureg ; D9 C0+r [8086,FPU]
FLD1 ; D9 E8 [8086,FPU]
FLDL2E ; D9 EA [8086,FPU]
FLDL2T ; D9 E9 [8086,FPU]
FLDLG2 ; D9 EC [8086,FPU]
FLDLN2 ; D9 ED [8086,FPU]
FLDPI ; D9 EB [8086,FPU]
FLDZ ; D9 EE [8086,FPU]
FLDCW mem16 ; D9 /5 [8086,FPU]
FLDENV mem ; D9 /4 [8086,FPU]
FMUL mem32 ; D8 /1 [8086,FPU]
FMUL mem64 ; DC /1 [8086,FPU]
FMUL fpureg ; D8 C8+r [8086,FPU]
FMUL ST0,fpureg ; D8 C8+r [8086,FPU]
FMUL TO fpureg ; DC C8+r [8086,FPU]
FMUL fpureg,ST0 ; DC C8+r [8086,FPU]
FMULP fpureg ; DE C8+r [8086,FPU]
FMULP fpureg,ST0 ; DE C8+r [8086,FPU]
FNOP ; D9 D0 [8086,FPU]
FPATAN ; D9 F3 [8086,FPU]
FPTAN ; D9 F2 [8086,FPU]
FPREM ; D9 F8 [8086,FPU]
FPREM1 ; D9 F5 [386,FPU]
FRNDINT ; D9 FC [8086,FPU]
FSAVE mem ; 9B DD /6 [8086,FPU]
FNSAVE mem ; DD /6 [8086,FPU]
FRSTOR mem ; DD /4 [8086,FPU]
FSCALE ; D9 FD [8086,FPU]
FSETPM ; DB E4 [286,FPU]
FSIN ; D9 FE [386,FPU]
FSINCOS ; D9 FB [386,FPU]
FSQRT ; D9 FA [8086,FPU]
FST mem32 ; D9 /2 [8086,FPU]
FST mem64 ; DD /2 [8086,FPU]
FST fpureg ; DD D0+r [8086,FPU]
FSTP mem32 ; D9 /3 [8086,FPU]
FSTP mem64 ; DD /3 [8086,FPU]
FSTP mem80 ; DB /0 [8086,FPU]
FSTP fpureg ; DD D8+r [8086,FPU]
FSTCW mem16 ; 9B D9 /0 [8086,FPU]
FNSTCW mem16 ; D9 /0 [8086,FPU]
FSTENV mem ; 9B D9 /6 [8086,FPU]
FNSTENV mem ; D9 /6 [8086,FPU]
FSTSW mem16 ; 9B DD /0 [8086,FPU]
FSTSW AX ; 9B DF E0 [286,FPU]
FNSTSW mem16 ; DD /0 [8086,FPU]
FNSTSW AX ; DF E0 [286,FPU]
FSUB mem32 ; D8 /4 [8086,FPU]
FSUB mem64 ; DC /4 [8086,FPU]
FSUB fpureg ; D8 E0+r [8086,FPU]
FSUB ST0,fpureg ; D8 E0+r [8086,FPU]
FSUB TO fpureg ; DC E8+r [8086,FPU]
FSUB fpureg,ST0 ; DC E8+r [8086,FPU]
FSUBR mem32 ; D8 /5 [8086,FPU]
FSUBR mem64 ; DC /5 [8086,FPU]
FSUBR fpureg ; D8 E8+r [8086,FPU]
FSUBR ST0,fpureg ; D8 E8+r [8086,FPU]
FSUBR TO fpureg ; DC E0+r [8086,FPU]
FSUBR fpureg,ST0 ; DC E0+r [8086,FPU]
FSUBP fpureg ; DE E8+r [8086,FPU]
FSUBP fpureg,ST0 ; DE E8+r [8086,FPU]
FSUBRP fpureg ; DE E0+r [8086,FPU]
FSUBRP fpureg,ST0 ; DE E0+r [8086,FPU]
FTST ; D9 E4 [8086,FPU]
FUCOM fpureg ; DD E0+r [386,FPU]
FUCOM ST0,fpureg ; DD E0+r [386,FPU]
FUCOMP fpureg ; DD E8+r [386,FPU]
FUCOMP ST0,fpureg ; DD E8+r [386,FPU]
FUCOMPP ; DA E9 [386,FPU]
FUCOMI fpureg ; DB E8+r [P6,FPU]
FUCOMI ST0,fpureg ; DB E8+r [P6,FPU]
FUCOMIP fpureg ; DF E8+r [P6,FPU]
FUCOMIP ST0,fpureg ; DF E8+r [P6,FPU]
FXAM ; D9 E5 [8086,FPU]
FXCH ; D9 C9 [8086,FPU]
FXCH fpureg ; D9 C8+r [8086,FPU]
FXCH fpureg,ST0 ; D9 C8+r [8086,FPU]
FXCH ST0,fpureg ; D9 C8+r [8086,FPU]
FXTRACT ; D9 F4 [8086,FPU]
FYL2X ; D9 F1 [8086,FPU]
FYL2XP1 ; D9 F9 [8086,FPU]
HLT ; F4 [8086]
IBTS r/m16,reg16 ; o16 0F A7 /r [386,UNDOC]
IBTS r/m32,reg32 ; o32 0F A7 /r [386,UNDOC]
IDIV r/m8 ; F6 /7 [8086]
IDIV r/m16 ; o16 F7 /7 [8086]
IDIV r/m32 ; o32 F7 /7 [386]
IMUL r/m8 ; F6 /5 [8086]
IMUL r/m16 ; o16 F7 /5 [8086]
IMUL r/m32 ; o32 F7 /5 [386]
IMUL reg16,r/m16 ; o16 0F AF /r [386]
IMUL reg32,r/m32 ; o32 0F AF /r [386]
IMUL reg16,imm8 ; o16 6B /r ib [286]
IMUL reg16,imm16 ; o16 69 /r iw [286]
IMUL reg32,imm8 ; o32 6B /r ib [386]
IMUL reg32,imm32 ; o32 69 /r id [386]
//IMUL reg16,r/m16,imm8 ; o16 6B /r ib [286]
//IMUL reg16,r/m16,imm16 ; o16 69 /r iw [286]
//IMUL reg32,r/m32,imm8 ; o32 6B /r ib [386]
//IMUL reg32,r/m32,imm32 ; o32 69 /r id [386]
IN AL,imm8 ; E4 ib [8086]
IN AX,imm8 ; o16 E5 ib [8086]
IN EAX,imm8 ; o32 E5 ib [386]
IN AL,DX ; EC [8086]
IN AX,DX ; o16 ED [8086]
IN EAX,DX ; o32 ED [386]
INC reg16 ; o16 40+r [8086]
INC reg32 ; o32 40+r [386]
INC r/m8 ; FE /0 [8086]
INC r/m16 ; o16 FF /0 [8086]
INC r/m32 ; o32 FF /0 [386]
INSB ; 6C [186]
INSW ; o16 6D [186]
INSD ; o32 6D [386]
INT imm8 ; CD ib [8086]
INT1 ; F1 [P6]
ICEBP ; F1 [P6]
INT01 ; F1 [P6]
INT3 ; CC [8086]
INTO ; CE [8086]
INVD ; 0F 08 [486]
INVLPG mem ; 0F 01 /0 [486]
IRET ; CF [8086]
IRETW ; o16 CF [8086]
IRETD ; o32 CF [386]
JCXZ imm ; o16 E3 rb [8086]
JECXZ imm ; o32 E3 rb [386]
JMP imm ; E9 rw/rd [8086]
JMP SHORT imm ; EB rb [8086]
//JMP imm:imm16 ; o16 EA iw iw [8086]
//JMP imm:imm32 ; o32 EA id iw [386]
//JMP FAR mem ; o16 FF /5 [8086]
//JMP FAR mem ; o32 FF /5 [386]
JMP r/m16 ; o16 FF /4 [8086]
JMP r/m32 ; o32 FF /4 [386]
LAHF ; 9F [8086]
LAR reg16,r/m16 ; o16 0F 02 /r [286,PRIV]
LAR reg32,r/m32 ; o32 0F 02 /r [286,PRIV]
LDS reg16,mem ; o16 C5 /r [8086]
LDS reg32,mem ; o32 C5 /r [8086]
LES reg16,mem ; o16 C4 /r [8086]
LES reg32,mem ; o32 C4 /r [8086]
LFS reg16,mem ; o16 0F B4 /r [386]
LFS reg32,mem ; o32 0F B4 /r [386]
LGS reg16,mem ; o16 0F B5 /r [386]
LGS reg32,mem ; o32 0F B5 /r [386]
LSS reg16,mem ; o16 0F B2 /r [386]
LSS reg32,mem ; o32 0F B2 /r [386]
LEA reg16,mem ; o16 8D /r [8086]
LEA reg32,mem ; o32 8D /r [8086]
LEAVE ; C9 [186]
LGDT mem ; 0F 01 /2 [286,PRIV]
LIDT mem ; 0F 01 /3 [286,PRIV]
LLDT r/m16 ; 0F 00 /2 [286,PRIV]
LMSW r/m16 ; 0F 01 /6 [286,PRIV]
LOADALL ; 0F 07 [386,UNDOC]
LOADALL286 ; 0F 05 [286,UNDOC]
LODSB ; AC [8086]
LODSW ; o16 AD [8086]
LODSD ; o32 AD [386]
LOOP imm ; E2 rb [8086]
LOOP imm,CX ; a16 E2 rb [8086]
LOOP imm,ECX ; a32 E2 rb [386]
LOOPE imm ; E1 rb [8086]
LOOPE imm,CX ; a16 E1 rb [8086]
LOOPE imm,ECX ; a32 E1 rb [386]
LOOPZ imm ; E1 rb [8086]
LOOPZ imm,CX ; a16 E1 rb [8086]
LOOPZ imm,ECX ; a32 E1 rb [386]
LOOPNE imm ; E0 rb [8086]
LOOPNE imm,CX ; a16 E0 rb [8086]
LOOPNE imm,ECX ; a32 E0 rb [386]
LOOPNZ imm ; E0 rb [8086]
LOOPNZ imm,CX ; a16 E0 rb [8086]
LOOPNZ imm,ECX ; a32 E0 rb [386]
LSL reg16,r/m16 ; o16 0F 03 /r [286,PRIV]
LSL reg32,r/m32 ; o32 0F 03 /r [286,PRIV]
LTR r/m16 ; 0F 00 /3 [286,PRIV]
MOV AL,memoffs8 ; A0 ow/od [8086]
MOV AX,memoffs16 ; o16 A1 ow/od [8086]
MOV EAX,memoffs32 ; o32 A1 ow/od [386]
MOV memoffs8,AL ; A2 ow/od [8086]
MOV memoffs16,AX ; o16 A3 ow/od [8086]
MOV memoffs32,EAX ; o32 A3 ow/od [386]
MOV r/m8,reg8 ; 88 /r [8086]
MOV r/m16,reg16 ; o16 89 /r [8086]
MOV r/m32,reg32 ; o32 89 /r [386]
MOV reg8,r/m8 ; 8A /r [8086]
MOV reg16,r/m16 ; o16 8B /r [8086]
MOV reg32,r/m32 ; o32 8B /r [386]
MOV reg8,imm8 ; B0+r ib [8086]
MOV reg16,imm16 ; o16 B8+r iw [8086]
MOV reg32,imm32 ; o32 B8+r id [386]
MOV r/m8,imm8 ; C6 /0 ib [8086]
MOV r/m16,imm16 ; o16 C7 /0 iw [8086]
MOV r/m32,imm32 ; o32 C7 /0 id [386]
MOV r/m16,segreg ; o16 8C /r [8086]
MOV r/m32,segreg ; o32 8C /r [386]
MOV segreg,r/m16 ; o16 8E /r [8086]
MOV segreg,r/m32 ; o32 8E /r [386]
MOV reg32,CR0/2/3/4 ; 0F 20 /r [386]
MOV reg32,DR0/1/2/3/6/7 ; 0F 21 /r [386]
MOV reg32,TR3/4/5/6/7 ; 0F 24 /r [386]
MOV CR0/2/3/4,reg32 ; 0F 22 /r [386]
MOV DR0/1/2/3/6/7,reg32 ; 0F 23 /r [386]
MOV TR3/4/5/6/7,reg32 ; 0F 26 /r [386]
MOVD mmxreg,r/m32 ; 0F 6E /r [PENT,MMX]
MOVD r/m32,mmxreg ; 0F 7E /r [PENT,MMX]
MOVQ mmxreg,r/m64 ; 0F 6F /r [PENT,MMX]
MOVQ r/m64,mmxreg ; 0F 7F /r [PENT,MMX]
MOVSB ; A4 [8086]
MOVSW ; o16 A5 [8086]
MOVSD ; o32 A5 [386]
MOVSX reg16,r/m8 ; o16 0F BE /r [386]
MOVSX reg32,r/m8 ; o32 0F BE /r [386]
MOVSX reg32,r/m16 ; o32 0F BF /r [386]
MOVZX reg16,r/m8 ; o16 0F B6 /r [386]
MOVZX reg32,r/m8 ; o32 0F B6 /r [386]
MOVZX reg32,r/m16 ; o32 0F B7 /r [386]
MUL r/m8 ; F6 /4 [8086]
MUL r/m16 ; o16 F7 /4 [8086]
MUL r/m32 ; o32 F7 /4 [386]
NEG r/m8 ; F6 /3 [8086]
NEG r/m16 ; o16 F7 /3 [8086]
NEG r/m32 ; o32 F7 /3 [386]
NOT r/m8 ; F6 /2 [8086]
NOT r/m16 ; o16 F7 /2 [8086]
NOT r/m32 ; o32 F7 /2 [386]
NOP ; 90 [8086]
OR AL,imm8 ; 0C ib [8086]
OR AX,imm16 ; o16 0D iw [8086]
OR EAX,imm32 ; o32 0D id [386]
OR r/m8,reg8 ; 08 /r [8086]
OR r/m16,reg16 ; o16 09 /r [8086]
OR r/m32,reg32 ; o32 09 /r [386]
OR reg8,r/m8 ; 0A /r [8086]
OR reg16,r/m16 ; o16 0B /r [8086]
OR reg32,r/m32 ; o32 0B /r [386]
OR r/m8,imm8 ; 80 /1 ib [8086]
OR r/m16,imm16 ; o16 81 /1 iw [8086]
OR r/m32,imm32 ; o32 81 /1 id [386]
OR r/m16,imm8 ; o16 83 /1 ib [8086]
OR r/m32,imm8 ; o32 83 /1 ib [386]
OUT imm8,AL ; E6 ib [8086]
OUT imm8,AX ; o16 E7 ib [8086]
OUT imm8,EAX ; o32 E7 ib [386]
OUT DX,AL ; EE [8086]
OUT DX,AX ; o16 EF [8086]
OUT DX,EAX ; o32 EF [386]
OUTSB ; 6E [186]
OUTSW ; o16 6F [186]
OUTSD ; o32 6F [386]
PACKSSDW mmxreg,r/m64 ; 0F 6B /r [PENT,MMX]
PACKSSWB mmxreg,r/m64 ; 0F 63 /r [PENT,MMX]
PACKUSWB mmxreg,r/m64 ; 0F 67 /r [PENT,MMX]
PADDB mmxreg,r/m64 ; 0F FC /r [PENT,MMX]
PADDW mmxreg,r/m64 ; 0F FD /r [PENT,MMX]
PADDD mmxreg,r/m64 ; 0F FE /r [PENT,MMX]
PADDSB mmxreg,r/m64 ; 0F EC /r [PENT,MMX]
PADDSW mmxreg,r/m64 ; 0F ED /r [PENT,MMX]
PADDUSB mmxreg,r/m64 ; 0F DC /r [PENT,MMX]
PADDUSW mmxreg,r/m64 ; 0F DD /r [PENT,MMX]
PADDSIW mmxreg,r/m64 ; 0F 51 /r [CYRIX,MMX]
PAND mmxreg,r/m64 ; 0F DB /r [PENT,MMX]
PANDN mmxreg,r/m64 ; 0F DF /r [PENT,MMX]
PAVEB mmxreg,r/m64 ; 0F 50 /r [CYRIX,MMX]
PCMPEQB mmxreg,r/m64 ; 0F 74 /r [PENT,MMX]
PCMPEQW mmxreg,r/m64 ; 0F 75 /r [PENT,MMX]
PCMPEQD mmxreg,r/m64 ; 0F 76 /r [PENT,MMX]
PCMPGTB mmxreg,r/m64 ; 0F 64 /r [PENT,MMX]
PCMPGTW mmxreg,r/m64 ; 0F 65 /r [PENT,MMX]
PCMPGTD mmxreg,r/m64 ; 0F 66 /r [PENT,MMX]
PDISTIB mmxreg,mem64 ; 0F 54 /r [CYRIX,MMX]
PMACHRIW mmxreg,mem64 ; 0F 5E /r [CYRIX,MMX]
PMADDWD mmxreg,r/m64 ; 0F F5 /r [PENT,MMX]
PMAGW mmxreg,r/m64 ; 0F 52 /r [CYRIX,MMX]
PMULHRW mmxreg,r/m64 ; 0F 59 /r [CYRIX,MMX]
PMULHRIW mmxreg,r/m64 ; 0F 5D /r [CYRIX,MMX]
PMULHW mmxreg,r/m64 ; 0F E5 /r [PENT,MMX]
PMULLW mmxreg,r/m64 ; 0F D5 /r [PENT,MMX]
PMVZB mmxreg,mem64 ; 0F 58 /r [CYRIX,MMX]
PMVNZB mmxreg,mem64 ; 0F 5A /r [CYRIX,MMX]
PMVLZB mmxreg,mem64 ; 0F 5B /r [CYRIX,MMX]
PMVGEZB mmxreg,mem64 ; 0F 5C /r [CYRIX,MMX]
POP reg16 ; o16 58+r [8086]
POP reg32 ; o32 58+r [386]
POP r/m16 ; o16 8F /0 [8086]
POP r/m32 ; o32 8F /0 [386]
POP CS ; 0F [8086,UNDOC]
POP DS ; 1F [8086]
POP ES ; 07 [8086]
POP SS ; 17 [8086]
POP FS ; 0F A1 [386]
POP GS ; 0F A9 [386]
POPA ; 61 [186]
POPAW ; o16 61 [186]
POPAD ; o32 61 [386]
POPF ; 9D [186]
POPFW ; o16 9D [186]
POPFD ; o32 9D [386]
POR mmxreg,r/m64 ; 0F EB /r [PENT,MMX]
PSLLW mmxreg,r/m64 ; 0F F1 /r [PENT,MMX]
PSLLW mmxreg,imm8 ; 0F 71 /6 ib [PENT,MMX]
PSLLD mmxreg,r/m64 ; 0F F2 /r [PENT,MMX]
PSLLD mmxreg,imm8 ; 0F 72 /6 ib [PENT,MMX]
PSLLQ mmxreg,r/m64 ; 0F F3 /r [PENT,MMX]
PSLLQ mmxreg,imm8 ; 0F 73 /6 ib [PENT,MMX]
PSRAW mmxreg,r/m64 ; 0F E1 /r [PENT,MMX]
PSRAW mmxreg,imm8 ; 0F 71 /4 ib [PENT,MMX]
PSRAD mmxreg,r/m64 ; 0F E2 /r [PENT,MMX]
PSRAD mmxreg,imm8 ; 0F 72 /4 ib [PENT,MMX]
PSRLW mmxreg,r/m64 ; 0F D1 /r [PENT,MMX]
PSRLW mmxreg,imm8 ; 0F 71 /2 ib [PENT,MMX]
PSRLD mmxreg,r/m64 ; 0F D2 /r [PENT,MMX]
PSRLD mmxreg,imm8 ; 0F 72 /2 ib [PENT,MMX]
PSRLQ mmxreg,r/m64 ; 0F D3 /r [PENT,MMX]
PSRLQ mmxreg,imm8 ; 0F 73 /2 ib [PENT,MMX]
PSUBB mmxreg,r/m64 ; 0F F8 /r [PENT,MMX]
PSUBW mmxreg,r/m64 ; 0F F9 /r [PENT,MMX]
PSUBD mmxreg,r/m64 ; 0F FA /r [PENT,MMX]
PSUBSB mmxreg,r/m64 ; 0F E8 /r [PENT,MMX]
PSUBSW mmxreg,r/m64 ; 0F E9 /r [PENT,MMX]
PSUBUSB mmxreg,r/m64 ; 0F D8 /r [PENT,MMX]
PSUBUSW mmxreg,r/m64 ; 0F D9 /r [PENT,MMX]
PSUBSIW mmxreg,r/m64 ; 0F 55 /r [CYRIX,MMX]
PUNPCKHBW mmxreg,r/m64 ; 0F 68 /r [PENT,MMX]
PUNPCKHWD mmxreg,r/m64 ; 0F 69 /r [PENT,MMX]
PUNPCKHDQ mmxreg,r/m64 ; 0F 6A /r [PENT,MMX]
PUNPCKLBW mmxreg,r/m64 ; 0F 60 /r [PENT,MMX]
PUNPCKLWD mmxreg,r/m64 ; 0F 61 /r [PENT,MMX]
PUNPCKLDQ mmxreg,r/m64 ; 0F 62 /r [PENT,MMX]
PUSH reg16 ; o16 50+r [8086]
PUSH reg32 ; o32 50+r [386]
PUSH r/m16 ; o16 FF /6 [8086]
PUSH r/m32 ; o32 FF /6 [386]
PUSH CS ; 0E [8086]
PUSH DS ; 1E [8086]
PUSH ES ; 06 [8086]
PUSH SS ; 16 [8086]
PUSH FS ; 0F A0 [386]
PUSH GS ; 0F A8 [386]
PUSH imm8 ; 6A ib [286]
PUSH imm16 ; o16 68 iw [286]
PUSH imm32 ; o32 68 id [386]
PUSHA ; 60 [186]
PUSHAD ; o32 60 [386]
PUSHAW ; o16 60 [186]
PUSHF ; 9C [186]
PUSHFD ; o32 9C [386]
PUSHFW ; o16 9C [186]
PXOR mmxreg,r/m64 ; 0F EF /r [PENT,MMX]
RCL r/m8,1 ; D0 /2 [8086]
RCL r/m8,CL ; D2 /2 [8086]
RCL r/m8,imm8 ; C0 /2 ib [286]
RCL r/m16,1 ; o16 D1 /2 [8086]
RCL r/m16,CL ; o16 D3 /2 [8086]
RCL r/m16,imm8 ; o16 C1 /2 ib [286]
RCL r/m32,1 ; o32 D1 /2 [386]
RCL r/m32,CL ; o32 D3 /2 [386]
RCL r/m32,imm8 ; o32 C1 /2 ib [386]
RCR r/m8,1 ; D0 /3 [8086]
RCR r/m8,CL ; D2 /3 [8086]
RCR r/m8,imm8 ; C0 /3 ib [286]
RCR r/m16,1 ; o16 D1 /3 [8086]
RCR r/m16,CL ; o16 D3 /3 [8086]
RCR r/m16,imm8 ; o16 C1 /3 ib [286]
RCR r/m32,1 ; o32 D1 /3 [386]
RCR r/m32,CL ; o32 D3 /3 [386]
RCR r/m32,imm8 ; o32 C1 /3 ib [386]
RDMSR ; 0F 32 [PENT]
RDPMC ; 0F 33 [P6]
RDTSC ; 0F 31 [PENT]
RET ; C3 [8086]
RET imm16 ; C2 iw [8086]
RETF ; CB [8086]
RETF imm16 ; CA iw [8086]
RETN ; C3 [8086]
RETN imm16 ; C2 iw [8086]
ROL r/m8,1 ; D0 /0 [8086]
ROL r/m8,CL ; D2 /0 [8086]
ROL r/m8,imm8 ; C0 /0 ib [286]
ROL r/m16,1 ; o16 D1 /0 [8086]
ROL r/m16,CL ; o16 D3 /0 [8086]
ROL r/m16,imm8 ; o16 C1 /0 ib [286]
ROL r/m32,1 ; o32 D1 /0 [386]
ROL r/m32,CL ; o32 D3 /0 [386]
ROL r/m32,imm8 ; o32 C1 /0 ib [386]
ROR r/m8,1 ; D0 /1 [8086]
ROR r/m8,CL ; D2 /1 [8086]
ROR r/m8,imm8 ; C0 /1 ib [286]
ROR r/m16,1 ; o16 D1 /1 [8086]
ROR r/m16,CL ; o16 D3 /1 [8086]
ROR r/m16,imm8 ; o16 C1 /1 ib [286]
ROR r/m32,1 ; o32 D1 /1 [386]
ROR r/m32,CL ; o32 D3 /1 [386]
ROR r/m32,imm8 ; o32 C1 /1 ib [386]
RSM ; 0F AA [PENT]
SAHF ; 9E [8086]
SAL r/m8,1 ; D0 /4 [8086]
SAL r/m8,CL ; D2 /4 [8086]
SAL r/m8,imm8 ; C0 /4 ib [286]
SAL r/m16,1 ; o16 D1 /4 [8086]
SAL r/m16,CL ; o16 D3 /4 [8086]
SAL r/m16,imm8 ; o16 C1 /4 ib [286]
SAL r/m32,1 ; o32 D1 /4 [386]
SAL r/m32,CL ; o32 D3 /4 [386]
SAL r/m32,imm8 ; o32 C1 /4 ib [386]
SAR r/m8,1 ; D0 /7 [8086]
SAR r/m8,CL ; D2 /7 [8086]
SAR r/m8,imm8 ; C0 /7 ib [286]
SAR r/m16,1 ; o16 D1 /7 [8086]
SAR r/m16,CL ; o16 D3 /7 [8086]
SAR r/m16,imm8 ; o16 C1 /7 ib [286]
SAR r/m32,1 ; o32 D1 /7 [386]
SAR r/m32,CL ; o32 D3 /7 [386]
SAR r/m32,imm8 ; o32 C1 /7 ib [386]
SALC ; D6 [8086,UNDOC]
SBB AL,imm8 ; 1C ib [8086]
SBB AX,imm16 ; o16 1D iw [8086]
SBB EAX,imm32 ; o32 1D id [386]
SBB r/m8,reg8 ; 18 /r [8086]
SBB r/m16,reg16 ; o16 19 /r [8086]
SBB r/m32,reg32 ; o32 19 /r [386]
SBB reg8,r/m8 ; 1A /r [8086]
SBB reg16,r/m16 ; o16 1B /r [8086]
SBB reg32,r/m32 ; o32 1B /r [386]
SBB r/m8,imm8 ; 80 /3 ib [8086]
SBB r/m16,imm16 ; o16 81 /3 iw [8086]
SBB r/m32,imm32 ; o32 81 /3 id [386]
SBB r/m16,imm8 ; o16 83 /3 ib [8086]
SBB r/m32,imm8 ; o32 83 /3 ib [8086]
SCASB ; AE [8086]
SCASW ; o16 AF [8086]
SCASD ; o32 AF [386]
SGDT mem ; 0F 01 /0 [286,PRIV]
SIDT mem ; 0F 01 /1 [286,PRIV]
SLDT r/m16 ; 0F 00 /0 [286,PRIV]
SHL r/m8,1 ; D0 /4 [8086]
SHL r/m8,CL ; D2 /4 [8086]
SHL r/m8,imm8 ; C0 /4 ib [286]
SHL r/m16,1 ; o16 D1 /4 [8086]
SHL r/m16,CL ; o16 D3 /4 [8086]
SHL r/m16,imm8 ; o16 C1 /4 ib [286]
SHL r/m32,1 ; o32 D1 /4 [386]
SHL r/m32,CL ; o32 D3 /4 [386]
SHL r/m32,imm8 ; o32 C1 /4 ib [386]
SHR r/m8,1 ; D0 /5 [8086]
SHR r/m8,CL ; D2 /5 [8086]
SHR r/m8,imm8 ; C0 /5 ib [286]
SHR r/m16,1 ; o16 D1 /5 [8086]
SHR r/m16,CL ; o16 D3 /5 [8086]
SHR r/m16,imm8 ; o16 C1 /5 ib [286]
SHR r/m32,1 ; o32 D1 /5 [386]
SHR r/m32,CL ; o32 D3 /5 [386]
SHR r/m32,imm8 ; o32 C1 /5 ib [386]
SHLD r/m16,reg16,imm8 ; o16 0F A4 /r ib [386]
SHLD r/m16,reg32,imm8 ; o32 0F A4 /r ib [386]
SHLD r/m16,reg16,CL ; o16 0F A5 /r [386]
SHLD r/m16,reg32,CL ; o32 0F A5 /r [386]
SHRD r/m16,reg16,imm8 ; o16 0F AC /r ib [386]
SHRD r/m32,reg32,imm8 ; o32 0F AC /r ib [386]
SHRD r/m16,reg16,CL ; o16 0F AD /r [386]
SHRD r/m32,reg32,CL ; o32 0F AD /r [386]
SMI ; F1 [386,UNDOC]
SMSW r/m16 ; 0F 01 /4 [286,PRIV]
STC ; F9 [8086]
STD ; FD [8086]
STI ; FB [8086]
STOSB ; AA [8086]
STOSW ; o16 AB [8086]
STOSD ; o32 AB [386]
STR r/m16 ; 0F 00 /1 [286,PRIV]
SUB AL,imm8 ; 2C ib [8086]
SUB AX,imm16 ; o16 2D iw [8086]
SUB EAX,imm32 ; o32 2D id [386]
SUB r/m8,reg8 ; 28 /r [8086]
SUB r/m16,reg16 ; o16 29 /r [8086]
SUB r/m32,reg32 ; o32 29 /r [386]
SUB reg8,r/m8 ; 2A /r [8086]
SUB reg16,r/m16 ; o16 2B /r [8086]
SUB reg32,r/m32 ; o32 2B /r [386]
SUB r/m8,imm8 ; 80 /5 ib [8086]
SUB r/m16,imm16 ; o16 81 /5 iw [8086]
SUB r/m32,imm32 ; o32 81 /5 id [386]
SUB r/m16,imm8 ; o16 83 /5 ib [8086]
SUB r/m32,imm8 ; o32 83 /5 ib [386]
TEST AL,imm8 ; A8 ib [8086]
TEST AX,imm16 ; o16 A9 iw [8086]
TEST EAX,imm32 ; o32 A9 id [386]
TEST r/m8,reg8 ; 84 /r [8086]
TEST r/m16,reg16 ; o16 85 /r [8086]
TEST r/m32,reg32 ; o32 85 /r [386]
TEST r/m8,imm8 ; F6 /7 ib [8086]
TEST r/m16,imm16 ; o16 F7 /7 iw [8086]
TEST r/m32,imm32 ; o32 F7 /7 id [386]
UMOV r/m8,reg8 ; 0F 10 /r [386,UNDOC]
UMOV r/m16,reg16 ; o16 0F 11 /r [386,UNDOC]
UMOV r/m32,reg32 ; o32 0F 11 /r [386,UNDOC]
UMOV reg8,r/m8 ; 0F 12 /r [386,UNDOC]
UMOV reg16,r/m16 ; o16 0F 13 /r [386,UNDOC]
UMOV reg32,r/m32 ; o32 0F 13 /r [386,UNDOC]
VERR r/m16 ; 0F 00 /4 [286,PRIV]
VERW r/m16 ; 0F 00 /5 [286,PRIV]
WAIT ; 9B [8086]
WBINVD ; 0F 09 [486]
WRMSR ; 0F 30 [PENT]
XADD r/m8,reg8 ; 0F C0 /r [486]
XADD r/m16,reg16 ; o16 0F C1 /r [486]
XADD r/m32,reg32 ; o32 0F C1 /r [486]
XBTS reg16,r/m16 ; o16 0F A6 /r [386,UNDOC]
XBTS reg32,r/m32 ; o32 0F A6 /r [386,UNDOC]
XCHG reg8,r/m8 ; 86 /r [8086]
XCHG reg16,r/m8 ; o16 87 /r [8086]
XCHG reg32,r/m32 ; o32 87 /r [386]
XCHG r/m8,reg8 ; 86 /r [8086]
XCHG r/m16,reg16 ; o16 87 /r [8086]
XCHG r/m32,reg32 ; o32 87 /r [386]
XCHG AX,reg16 ; o16 90+r [8086]
XCHG EAX,reg32 ; o32 90+r [386]
XCHG reg16,AX ; o16 90+r [8086]
XCHG reg32,EAX ; o32 90+r [386]
XLATB ; D7 [8086]
XOR AL,imm8 ; 34 ib [8086]
XOR AX,imm16 ; o16 35 iw [8086]
XOR EAX,imm32 ; o32 35 id [386]
XOR r/m8,reg8 ; 30 /r [8086]
XOR r/m16,reg16 ; o16 31 /r [8086]
XOR r/m32,reg32 ; o32 31 /r [386]
XOR reg8,r/m8 ; 32 /r [8086]
XOR reg16,r/m16 ; o16 33 /r [8086]
XOR reg32,r/m32 ; o32 33 /r [386]
XOR r/m8,imm8 ; 80 /6 ib [8086]
XOR r/m16,imm16 ; o16 81 /6 iw [8086]
XOR r/m32,imm32 ; o32 81 /6 id [386]
XOR r/m16,imm8 ; o16 83 /6 ib [8086]
XOR r/m32,imm8 ; o32 83 /6 ib [386]
-13
View File
@@ -1,13 +0,0 @@
#ifndef LABEL_H
#define LABEL_H
struct Label {
string name; //name of label
int def, ref; //pos of defn and goto/restore src
int data_sz; //size of data at this label.
Label(const string& n, int d, int r, int sz) : name(n), def(d), ref(r), data_sz(sz) {}
};
#endif
+116
View File
@@ -0,0 +1,116 @@
project(compiler_lib)
set(PRIVATE_SOURCE
"assem.hpp"
"codegen.hpp"
"decl.cpp"
"decl.hpp"
"declnode.cpp"
"declnode.hpp"
"environ.cpp"
"environ.hpp"
"ex.hpp"
"exprnode.cpp"
"exprnode.hpp"
"label.hpp"
"node.cpp"
"node.hpp"
"parser.cpp"
"parser.hpp"
"prognode.cpp"
"prognode.hpp"
"stmtnode.cpp"
"stmtnode.hpp"
"toker.cpp"
"toker.hpp"
"type.cpp"
"type.hpp"
"var.hpp"
"varnode.cpp"
"varnode.hpp"
"assem_x86/assem_x86.hpp"
"assem_x86/assem_x86.cpp"
"assem_x86/operand.hpp"
"assem_x86/operand.cpp"
"assem_x86/insts.hpp"
"assem_x86/insts.cpp"
"codegen_x86/codegen_x86.hpp"
"codegen_x86/codegen_x86.cpp"
"codegen_x86/tile.hpp"
"codegen_x86/tile.cpp"
)
set(PRIVATE_HEADER
${PRIVATE_SOURCE}
)
list(FILTER PRIVATE_SOURCE EXCLUDE REGEX "^.*.hpp.*$")
list(FILTER PRIVATE_HEADER EXCLUDE REGEX "^.*.cpp.*$")
add_library(${PROJECT_NAME} STATIC
${PRIVATE_SOURCE}
${PRIVATE_HEADER}
)
source_group(TREE "${PROJECT_SOURCE_DIR}" PREFIX "Source Files" FILES ${PRIVATE_SOURCE})
source_group(TREE "${PROJECT_SOURCE_DIR}" PREFIX "Header Files" FILES ${PRIVATE_HEADER})
target_link_libraries(${PROJECT_NAME}
config
stdutil
linker
)
target_include_directories(${PROJECT_NAME}
PUBLIC
${PROJECT_SOURCE_DIR}
)
if (WIN32)
target_compile_definitions(${PROJECT_NAME}
PRIVATE
_CRT_SECURE_NO_WARNINGS
# windows.h
WIN32_LEAN_AND_MEAN
NOGPICAPMASKS
NOVIRTUALKEYCODES
NOWINMESSAGES
NOWINSTYLES
NOSYSMETRICS
NOMENUS
NOICONS
NOKEYSTATES
NOSYSCOMMANDS
NORASTEROPS
NOSHOWWINDOW
NOATOM
NOCLIPBOARD
NOCOLOR
NOCTLMGR
NODRAWTEXT
NOGDI
NOKERNEL
NOUSER
NONLS
NOMB
NOMEMMGR
NOMETAFILE
NOMINMAX
NOMSG
NOOPENFILE
NOSCROLL
NOSERVICE
NOSOUND
NOTEXTMETRIC
NOWH
NOWINOFFSETS
NOCOMM
NOKANJI
NOHELP
NOPROFILER
NODEFERWINDOWPOS
NOMCX
NOIME
NOMDI
NOINOUT
)
endif()
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include <istream>
#include <linker.hpp>
class Assem {
public:
std::istream& in;
Module* mod;
Assem(std::istream& in, Module* mod) : in(in), mod(mod) {}
virtual void assemble() = 0;
};
@@ -1,27 +1,24 @@
/* BlitzPC assembler.
This REALLY needs some work - very slow. */
/* #include "assem_x86.hpp"
#include <map>
BlitzPC assembler. #include "../ex.hpp"
#include "insts.hpp"
This REALLY needs some work - very slow. #include "operand.hpp"
#include <istream>
*/
#include "assem_x86.h"
#include "../ex.h"
#include "../std.h"
#include <iomanip> #include <iomanip>
typedef map<string, Inst*> InstMap; typedef std::map<std::string, Inst*> InstMap;
typedef InstMap::value_type InstPair; typedef InstMap::value_type InstPair;
typedef InstMap::const_iterator InstIter; typedef InstMap::const_iterator InstIter;
static InstMap instMap; static InstMap instMap;
//#define LOG //#define LOG
Assem_x86::Assem_x86(istream& in, Module* mod) : Assem(in, mod) Assem_x86::Assem_x86(std::istream& in, Module* mod) : Assem(in, mod)
{ {
//build instruction map, if not built already. //build instruction map, if not built already.
if (!instMap.size()) { if (!instMap.size()) {
@@ -32,7 +29,7 @@ Assem_x86::Assem_x86(istream& in, Module* mod) : Assem(in, mod)
} }
} }
static int findCC(const string& s) static int findCC(const std::string& s)
{ {
if (s == "o") if (s == "o")
return 0; return 0;
@@ -100,7 +97,7 @@ void Assem_x86::emitd(int n)
void Assem_x86::emitImm(const Operand& o, int size) void Assem_x86::emitImm(const Operand& o, int size)
{ {
if (size < 4 && o.immLabel.size()) if (size < 4 && o.immLabel.size())
throw Ex("immediate value cannot by a label"); throw BlitzException("immediate value cannot by a label");
switch (size) { switch (size) {
case 1: case 1:
@@ -116,30 +113,30 @@ void Assem_x86::emitImm(const Operand& o, int size)
} }
} }
void Assem_x86::emitImm(const string& s, int size) void Assem_x86::emitImm(const std::string& s, int size)
{ {
Operand op(s); Operand op(s);
op.parse(); op.parse();
if (!(op.mode & IMM)) if (!(op.mode & IMM))
throw Ex("operand must be immediate"); throw BlitzException("operand must be immediate");
emitImm(op, size); emitImm(op, size);
} }
void Assem_x86::r_reloc(const string& s) void Assem_x86::r_reloc(const std::string& s)
{ {
if (!s.size()) if (!s.size())
return; return;
mod->addReloc(s.c_str(), mod->getPC(), true); mod->addReloc(s.c_str(), mod->getPC(), true);
} }
void Assem_x86::a_reloc(const string& s) void Assem_x86::a_reloc(const std::string& s)
{ {
if (!s.size()) if (!s.size())
return; return;
mod->addReloc(s.c_str(), mod->getPC(), false); mod->addReloc(s.c_str(), mod->getPC(), false);
} }
void Assem_x86::assemInst(const string& name, const string& lhs, const string& rhs) void Assem_x86::assemInst(const std::string& name, const std::string& lhs, const std::string& rhs)
{ {
//parse operands //parse operands
Operand lop(lhs), rop(rhs); Operand lop(lhs), rop(rhs);
@@ -165,17 +162,17 @@ void Assem_x86::assemInst(const string& name, const string& lhs, const string& r
if (inst) { if (inst) {
if (!(lop.mode & inst->lmode) || !(rop.mode & inst->rmode)) if (!(lop.mode & inst->lmode) || !(rop.mode & inst->rmode))
throw Ex("illegal addressing mode"); throw BlitzException("illegal addressing mode");
} else { } else {
InstIter it = instMap.find(name); InstIter it = instMap.find(name);
if (it == instMap.end()) if (it == instMap.end())
throw Ex("unrecognized instruction"); throw BlitzException("unrecognized instruction");
inst = it->second; inst = it->second;
for (;;) { for (;;) {
if ((lop.mode & inst->lmode) && (rop.mode & inst->rmode)) if ((lop.mode & inst->lmode) && (rop.mode & inst->rmode))
break; break;
if ((++inst)->name) if ((++inst)->name)
throw Ex("illegal addressing mode"); throw BlitzException("illegal addressing mode");
} }
} }
@@ -292,17 +289,17 @@ void Assem_x86::assemInst(const string& name, const string& lhs, const string& r
} }
} }
void Assem_x86::assemDir(const string& name, const string& op) void Assem_x86::assemDir(const std::string& name, const std::string& op)
{ {
if (!op.size()) if (!op.size())
throw Ex("operand error"); throw BlitzException("operand error");
if (name == ".db") { if (name == ".db") {
if (op[0] != '\"') if (op[0] != '\"')
emitImm(op, 1); emitImm(op, 1);
else { else {
if (op.size() < 2 || op[op.size() - 1] != '\"') if (op.size() < 2 || op[op.size() - 1] != '\"')
throw Ex("operand error"); throw BlitzException("operand error");
for (int k = 1; k < op.size() - 1; ++k) for (int k = 1; k < op.size() - 1; ++k)
emit(op[k]); emit(op[k]);
} }
@@ -314,26 +311,26 @@ void Assem_x86::assemDir(const string& name, const string& op)
Operand o(op); Operand o(op);
o.parse(); o.parse();
if (!(o.mode & IMM)) if (!(o.mode & IMM))
throw Ex("operand must be immediate"); throw BlitzException("operand must be immediate");
align(o.imm); align(o.imm);
} else { } else {
throw Ex("unrecognized assembler directive"); throw BlitzException("unrecognized assembler directive");
} }
} }
void Assem_x86::assemLine(const string& line) void Assem_x86::assemLine(const std::string& line)
{ {
int i = 0; int i = 0;
string name; std::string name;
vector<string> ops; std::vector<std::string> ops;
//label? //label?
if (!isspace(line[i])) { if (!isspace(line[i])) {
while (!isspace(line[i])) while (!isspace(line[i]))
++i; ++i;
string lab = line.substr(0, i); std::string lab = line.substr(0, i);
if (!mod->addSymbol(lab.c_str(), mod->getPC())) if (!mod->addSymbol(lab.c_str(), mod->getPC()))
throw Ex("duplicate label"); throw BlitzException("duplicate label");
} }
//skip space //skip space
@@ -360,7 +357,7 @@ void Assem_x86::assemLine(const string& line)
for (++i; line[i] != '\"' && line[i] != '\n'; ++i) { for (++i; line[i] != '\"' && line[i] != '\n'; ++i) {
} }
if (line[i++] != '\"') if (line[i++] != '\"')
throw Ex("missing close quote"); throw BlitzException("missing close quote");
} else { } else {
for (++i; line[i] != ',' && line[i] != ';' && line[i] != '\n'; ++i) { for (++i; line[i] != ',' && line[i] != ';' && line[i] != '\n'; ++i) {
} }
@@ -378,7 +375,7 @@ void Assem_x86::assemLine(const string& line)
break; break;
if (line[i++] != ',') if (line[i++] != ',')
throw Ex("expecting ','"); throw BlitzException("expecting ','");
} }
//pseudo op? //pseudo op?
@@ -390,7 +387,7 @@ void Assem_x86::assemLine(const string& line)
//normal instruction! //normal instruction!
if (ops.size() > 2) if (ops.size() > 2)
throw Ex("Too many operands"); throw BlitzException("Too many operands");
ops.push_back(""); ops.push_back("");
ops.push_back(""); ops.push_back("");
assemInst(name, ops[0], ops[1]); assemInst(name, ops[0], ops[1]);
@@ -398,11 +395,11 @@ void Assem_x86::assemLine(const string& line)
void Assem_x86::assemble() void Assem_x86::assemble()
{ {
string line; std::string line;
while (!in.eof()) { while (!in.eof()) {
try { try {
getline(in, line); std::getline(in, line);
line += '\n'; line += '\n';
#ifdef LOG #ifdef LOG
clog << line; clog << line;
@@ -411,8 +408,8 @@ void Assem_x86::assemble()
#ifdef LOG #ifdef LOG
clog << endl; clog << endl;
#endif #endif
} catch (Ex& x) { } catch (BlitzException& x) {
throw Ex(line + x.ex); throw BlitzException(line + x.ex);
} }
} }
} }
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include <iostream>
#include <istream>
#include <string>
#include <vector>
#include "assem.hpp"
class Module;
struct Operand;
class Assem_x86 : public Assem {
public:
Assem_x86(std::istream& in, Module* mod);
virtual void assemble();
private:
void align(int n);
void emit(int n);
void emitw(int n);
void emitd(int n);
void emitImm(const std::string& s, int size);
void emitImm(const Operand& o, int size);
void r_reloc(const std::string& dest);
void a_reloc(const std::string& dest);
void assemDir(const std::string& name, const std::string& op);
void assemInst(const std::string& name, const std::string& lhs, const std::string& rhs);
void assemLine(const std::string& line);
};
+582
View File
@@ -0,0 +1,582 @@
//
//This is generated code - do not modify!!!!!
//
#include "insts.hpp"
Inst insts[]={
"aaa",NONE,NONE,0,"\x1\x37",
"aas",NONE,NONE,0,"\x1\x3F",
"aad",NONE,NONE,0,"\x2\xD5\x0A",
0,IMM,NONE,IB,"\x1\xD5",
"aam",NONE,NONE,0,"\x2\xD4\x0A",
0,IMM,NONE,IB,"\x1\xD4",
"adc",AL,IMM8,IB,"\x1\x14",
0,AX,IMM16,O16|IW,"\x1\x15",
0,EAX,IMM32,O32|ID,"\x1\x15",
0,R_M8,REG8,_R,"\x1\x10",
0,R_M16,REG16,O16|_R,"\x1\x11",
0,R_M32,REG32,O32|_R,"\x1\x11",
0,REG8,R_M8,_R,"\x1\x12",
0,REG16,R_M16,O16|_R,"\x1\x13",
0,REG32,R_M32,O32|_R,"\x1\x13",
0,R_M8,IMM8,_2|IB,"\x1\x80",
0,R_M16,IMM16,O16|_2|IW,"\x1\x81",
0,R_M32,IMM32,O32|_2|ID,"\x1\x81",
0,R_M16,IMM8,O16|_2|IB,"\x1\x83",
0,R_M32,IMM8,O32|_2|IB,"\x1\x83",
"add",AL,IMM8,IB,"\x1\x04",
0,AX,IMM16,O16|IW,"\x1\x05",
0,EAX,IMM32,O32|ID,"\x1\x05",
0,R_M8,REG8,_R,"\x1\x00",
0,R_M16,REG16,O16|_R,"\x1\x01",
0,R_M32,REG32,O32|_R,"\x1\x01",
0,REG8,R_M8,_R,"\x1\x02",
0,REG16,R_M16,O16|_R,"\x1\x03",
0,REG32,R_M32,O32|_R,"\x1\x03",
0,R_M8,IMM8,_0|IB,"\x1\x80",
0,R_M16,IMM16,O16|_0|IW,"\x1\x81",
0,R_M32,IMM32,O32|_0|ID,"\x1\x81",
0,R_M16,IMM8,O16|_0|IB,"\x1\x83",
0,R_M32,IMM8,O32|_0|IB,"\x1\x83",
"and",AL,IMM8,IB,"\x1\x24",
0,AX,IMM16,O16|IW,"\x1\x25",
0,EAX,IMM32,O32|ID,"\x1\x25",
0,R_M8,REG8,_R,"\x1\x20",
0,R_M16,REG16,O16|_R,"\x1\x21",
0,R_M32,REG32,O32|_R,"\x1\x21",
0,REG8,R_M8,_R,"\x1\x22",
0,REG16,R_M16,O16|_R,"\x1\x23",
0,REG32,R_M32,O32|_R,"\x1\x23",
0,R_M8,IMM8,_4|IB,"\x1\x80",
0,R_M16,IMM16,O16|_4|IW,"\x1\x81",
0,R_M32,IMM32,O32|_4|ID,"\x1\x81",
0,R_M16,IMM8,O16|_4|IB,"\x1\x83",
0,R_M32,IMM8,O32|_4|IB,"\x1\x83",
"arpl",R_M16,REG16,_R,"\x1\x63",
"bound",REG16,MEM,O16|_R,"\x1\x62",
0,REG32,MEM,O32|_R,"\x1\x62",
"bsf",REG16,R_M16,O16|_R,"\x2\x0F\xBC",
0,REG32,R_M32,O32|_R,"\x2\x0F\xBC",
"bsr",REG16,R_M16,O16|_R,"\x2\x0F\xBD",
0,REG32,R_M32,O32|_R,"\x2\x0F\xBD",
"bswap",REG32,NONE,O32|PLUSREG,"\x2\x0F\xC8",
"bt",R_M16,REG16,O16|_R,"\x2\x0F\xA3",
0,R_M32,REG32,O32|_R,"\x2\x0F\xA3",
0,R_M16,IMM8,O16|_4|IB,"\x2\x0F\xBA",
0,R_M32,IMM8,O32|_4|IB,"\x2\x0F\xBA",
"btc",R_M16,REG16,O16|_R,"\x2\x0F\xBB",
0,R_M32,REG32,O32|_R,"\x2\x0F\xBB",
0,R_M16,IMM8,O16|_7|IB,"\x2\x0F\xBA",
0,R_M32,IMM8,O32|_7|IB,"\x2\x0F\xBA",
"btr",R_M16,REG16,O16|_R,"\x2\x0F\xB3",
0,R_M32,REG32,O32|_R,"\x2\x0F\xB3",
0,R_M16,IMM8,O16|_6|IB,"\x2\x0F\xBA",
0,R_M32,IMM8,O32|_6|IB,"\x2\x0F\xBA",
"bts",R_M16,REG16,O16|_R,"\x2\x0F\xAB",
0,R_M32,REG32,O32|_R,"\x2\x0F\xAB",
0,R_M16,IMM,O16|_5|IB,"\x2\x0F\xBA",
0,R_M32,IMM,O32|_5|IB,"\x2\x0F\xBA",
"call",IMM,NONE,RW_RD,"\x1\xE8",
0,R_M16,NONE,O16|_2,"\x1\xFF",
0,R_M32,NONE,O32|_2,"\x1\xFF",
"cbw",NONE,NONE,O16,"\x1\x98",
"cwd",NONE,NONE,O16,"\x1\x99",
"cdq",NONE,NONE,O32,"\x1\x99",
"cwde",NONE,NONE,O32,"\x1\x98",
"clc",NONE,NONE,0,"\x1\xF8",
"cld",NONE,NONE,0,"\x1\xFC",
"cli",NONE,NONE,0,"\x1\xFA",
"clts",NONE,NONE,0,"\x2\x0F\x06",
"cmc",NONE,NONE,0,"\x1\xF5",
"cmovcc",REG16,R_M16,O16|PLUSCC|_R,"\x2\x0F\x40",
0,REG32,R_M32,O32|PLUSCC|_R,"\x2\x0F\x40",
"cmp",AL,IMM8,IB,"\x1\x3C",
0,AX,IMM16,O16|IW,"\x1\x3D",
0,EAX,IMM32,O32|ID,"\x1\x3D",
0,R_M8,REG8,_R,"\x1\x38",
0,R_M16,REG16,O16|_R,"\x1\x39",
0,R_M32,REG32,O32|_R,"\x1\x39",
0,REG8,R_M8,_R,"\x1\x3A",
0,REG16,R_M16,O16|_R,"\x1\x3B",
0,REG32,R_M32,O32|_R,"\x1\x3B",
0,R_M8,IMM8,_7|IB,"\x1\x80",
0,R_M16,IMM16,O16|_7|IW,"\x1\x81",
0,R_M32,IMM32,O32|_7|ID,"\x1\x81",
0,R_M16,IMM8,O16|_7|IB,"\x1\x83",
0,R_M32,IMM8,O32|_7|IB,"\x1\x83",
"cmpsb",NONE,NONE,0,"\x1\xA6",
"cmpsw",NONE,NONE,O16,"\x1\xA7",
"cmpsd",NONE,NONE,O32,"\x1\xA7",
"cmpxchg",R_M8,REG8,_R,"\x2\x0F\xB0",
0,R_M16,REG16,O16|_R,"\x2\x0F\xB1",
0,R_M32,REG32,O32|_R,"\x2\x0F\xB1",
"cmpxchg486",R_M8,REG8,_R,"\x2\x0F\xA6",
0,R_M16,REG16,O16|_R,"\x2\x0F\xA7",
0,R_M32,REG32,O32|_R,"\x2\x0F\xA7",
"cmpxchg8b",MEM,NONE,_1,"\x2\x0F\xC7",
"cpuid",NONE,NONE,0,"\x2\x0F\xA2",
"daa",NONE,NONE,0,"\x1\x27",
"das",NONE,NONE,0,"\x1\x2F",
"dec",REG16,NONE,O16|PLUSREG,"\x1\x48",
0,REG32,NONE,O32|PLUSREG,"\x1\x48",
0,R_M8,NONE,_1,"\x1\xFE",
0,R_M16,NONE,O16|_1,"\x1\xFF",
0,R_M32,NONE,O32|_1,"\x1\xFF",
"div",R_M8,NONE,_6,"\x1\xF6",
0,R_M16,NONE,O16|_6,"\x1\xF7",
0,R_M32,NONE,O32|_6,"\x1\xF7",
"emms",NONE,NONE,0,"\x2\x0F\x77",
"enter",IMM,IMM,IW|IB,"\x1\xC8",
"f2xm1",NONE,NONE,0,"\x2\xD9\xF0",
"fabs",NONE,NONE,0,"\x2\xD9\xE1",
"fadd",MEM32,NONE,_0,"\x1\xD8",
0,FPUREG,NONE,PLUSREG,"\x2\xD8\xC0",
0,ST0,FPUREG,PLUSREG,"\x2\xD8\xC0",
0,FPUREG,ST0,PLUSREG,"\x2\xDC\xC0",
"faddp",FPUREG,NONE,PLUSREG,"\x2\xDE\xC0",
0,FPUREG,ST0,PLUSREG,"\x2\xDE\xC0",
"fchs",NONE,NONE,0,"\x2\xD9\xE0",
"fclex",NONE,NONE,0,"\x4\x9B\xDB\xE2",
"fnclex",NONE,NONE,0,"\x2\xDB\xE2",
"fcmovb",FPUREG,NONE,PLUSREG,"\x2\xDA\xC0",
0,ST0,FPUREG,PLUSREG,"\x2\xDA\xC0",
"fcmovbe",FPUREG,NONE,PLUSREG,"\x2\xDA\xD0",
0,ST0,FPUREG,PLUSREG,"\x2\xDA\xD0",
"fcmove",FPUREG,NONE,PLUSREG,"\x2\xDA\xC8",
0,ST0,FPUREG,PLUSREG,"\x2\xDA\xC8",
"fcmovnb",FPUREG,NONE,PLUSREG,"\x2\xDB\xC0",
0,ST0,FPUREG,PLUSREG,"\x2\xDB\xC0",
"fcmovnbe",FPUREG,NONE,PLUSREG,"\x2\xDB\xD0",
0,ST0,FPUREG,PLUSREG,"\x2\xDB\xD0",
"fcmovne",FPUREG,NONE,PLUSREG,"\x2\xDB\xC8",
0,ST0,FPUREG,PLUSREG,"\x2\xDB\xC8",
"fcmovnu",FPUREG,NONE,PLUSREG,"\x2\xDB\xD8",
0,ST0,FPUREG,PLUSREG,"\x2\xDB\xD8",
"fcmovu",FPUREG,NONE,PLUSREG,"\x2\xDA\xD8",
0,ST0,FPUREG,PLUSREG,"\x2\xDA\xD8",
"fcom",MEM32,NONE,_2,"\x1\xD8",
0,FPUREG,NONE,PLUSREG,"\x2\xD8\xD0",
0,ST0,FPUREG,PLUSREG,"\x2\xD8\xD0",
"fcomp",MEM32,NONE,_3,"\x1\xD8",
0,FPUREG,NONE,PLUSREG,"\x2\xD8\xD8",
0,ST0,FPUREG,PLUSREG,"\x2\xD8\xD8",
"fcompp",NONE,NONE,0,"\x2\xDE\xD9",
"fcomi",FPUREG,NONE,PLUSREG,"\x2\xDB\xF0",
0,ST0,FPUREG,PLUSREG,"\x2\xDB\xF0",
"fcomip",FPUREG,NONE,PLUSREG,"\x2\xDF\xF0",
0,ST0,FPUREG,PLUSREG,"\x2\xDF\xF0",
"fcos",NONE,NONE,0,"\x2\xD9\xFF",
"fdecstp",NONE,NONE,0,"\x2\xD9\xF6",
"fdisi",NONE,NONE,0,"\x4\x9B\xDB\xE1",
"fndisi",NONE,NONE,0,"\x2\xDB\xE1",
"feni",NONE,NONE,0,"\x4\x9B\xDB\xE0",
"fneni",NONE,NONE,0,"\x2\xDB\xE0",
"fdiv",MEM32,NONE,_6,"\x1\xD8",
0,FPUREG,NONE,PLUSREG,"\x2\xD8\xF0",
0,ST0,FPUREG,PLUSREG,"\x2\xD8\xF0",
0,FPUREG,ST0,PLUSREG,"\x2\xDC\xF8",
"fdivr",MEM32,NONE,_0,"\x1\xD8",
0,FPUREG,NONE,PLUSREG,"\x2\xD8\xF8",
0,ST0,FPUREG,PLUSREG,"\x2\xD8\xF8",
0,FPUREG,ST0,PLUSREG,"\x2\xDC\xF0",
"fdivp",FPUREG,NONE,PLUSREG,"\x2\xDE\xF8",
0,FPUREG,ST0,PLUSREG,"\x2\xDE\xF8",
"fdivrp",FPUREG,NONE,PLUSREG,"\x2\xDE\xF0",
0,FPUREG,ST0,PLUSREG,"\x2\xDE\xF0",
"ffree",FPUREG,NONE,PLUSREG,"\x2\xDD\xC0",
"fiadd",MEM16,NONE,_0,"\x1\xDE",
0,MEM32,NONE,_0,"\x1\xDA",
"ficom",MEM16,NONE,_2,"\x1\xDE",
0,MEM32,NONE,_2,"\x1\xDA",
"ficomp",MEM16,NONE,_3,"\x1\xDE",
0,MEM32,NONE,_3,"\x1\xDA",
"fidiv",MEM16,NONE,_6,"\x1\xDE",
0,MEM32,NONE,_6,"\x1\xDA",
"fidivr",MEM16,NONE,_0,"\x1\xDE",
0,MEM32,NONE,_0,"\x1\xDA",
"fild",MEM16,NONE,_0,"\x1\xDF",
0,MEM32,NONE,_0,"\x1\xDB",
"fist",MEM16,NONE,_2,"\x1\xDF",
0,MEM32,NONE,_2,"\x1\xDB",
"fistp",MEM16,NONE,_3,"\x1\xDF",
0,MEM32,NONE,_3,"\x1\xDB",
"fimul",MEM16,NONE,_1,"\x1\xDE",
0,MEM32,NONE,_1,"\x1\xDA",
"fincstp",NONE,NONE,0,"\x2\xD9\xF7",
"finit",NONE,NONE,0,"\x4\x9B\xDB\xE3",
"fninit",NONE,NONE,0,"\x2\xDB\xE3",
"fisub",MEM16,NONE,_4,"\x1\xDE",
0,MEM32,NONE,_4,"\x1\xDA",
"fisubr",MEM16,NONE,_5,"\x1\xDE",
0,MEM32,NONE,_5,"\x1\xDA",
"fld",MEM32,NONE,_0,"\x1\xD9",
0,FPUREG,NONE,PLUSREG,"\x2\xD9\xC0",
"fld1",NONE,NONE,0,"\x2\xD9\xE8",
"fldl2e",NONE,NONE,0,"\x2\xD9\xEA",
"fldl2t",NONE,NONE,0,"\x2\xD9\xE9",
"fldlg2",NONE,NONE,0,"\x2\xD9\xEC",
"fldln2",NONE,NONE,0,"\x2\xD9\xED",
"fldpi",NONE,NONE,0,"\x2\xD9\xEB",
"fldz",NONE,NONE,0,"\x2\xD9\xEE",
"fldcw",MEM16,NONE,_5,"\x1\xD9",
"fldenv",MEM,NONE,_4,"\x1\xD9",
"fmul",MEM32,NONE,_1,"\x1\xD8",
0,FPUREG,NONE,PLUSREG,"\x2\xD8\xC8",
0,ST0,FPUREG,PLUSREG,"\x2\xD8\xC8",
0,FPUREG,ST0,PLUSREG,"\x2\xDC\xC8",
"fmulp",FPUREG,NONE,PLUSREG,"\x2\xDE\xC8",
0,FPUREG,ST0,PLUSREG,"\x2\xDE\xC8",
"fnop",NONE,NONE,0,"\x2\xD9\xD0",
"fpatan",NONE,NONE,0,"\x2\xD9\xF3",
"fptan",NONE,NONE,0,"\x2\xD9\xF2",
"fprem",NONE,NONE,0,"\x2\xD9\xF8",
"fprem1",NONE,NONE,0,"\x2\xD9\xF5",
"frndint",NONE,NONE,0,"\x2\xD9\xFC",
"fsave",MEM,NONE,_6,"\x2\x9B\xDD",
"fnsave",MEM,NONE,_6,"\x1\xDD",
"frstor",MEM,NONE,_4,"\x1\xDD",
"fscale",NONE,NONE,0,"\x2\xD9\xFD",
"fsetpm",NONE,NONE,0,"\x2\xDB\xE4",
"fsin",NONE,NONE,0,"\x2\xD9\xFE",
"fsincos",NONE,NONE,0,"\x2\xD9\xFB",
"fsqrt",NONE,NONE,0,"\x2\xD9\xFA",
"fst",MEM32,NONE,_2,"\x1\xD9",
0,FPUREG,NONE,PLUSREG,"\x2\xDD\xD0",
"fstp",MEM32,NONE,_3,"\x1\xD9",
0,FPUREG,NONE,PLUSREG,"\x2\xDD\xD8",
"fstcw",MEM16,NONE,_0,"\x2\x9B\xD9",
"fnstcw",MEM16,NONE,_0,"\x1\xD9",
"fstenv",MEM,NONE,_6,"\x2\x9B\xD9",
"fnstenv",MEM,NONE,_6,"\x1\xD9",
"fstsw",MEM16,NONE,_0,"\x2\x9B\xDD",
0,AX,NONE,0,"\x4\x9B\xDF\xE0",
"fnstsw",MEM16,NONE,_0,"\x1\xDD",
0,AX,NONE,0,"\x2\xDF\xE0",
"fsub",MEM32,NONE,_4,"\x1\xD8",
0,FPUREG,NONE,PLUSREG,"\x2\xD8\xE0",
0,ST0,FPUREG,PLUSREG,"\x2\xD8\xE0",
0,FPUREG,ST0,PLUSREG,"\x2\xDC\xE8",
"fsubr",MEM32,NONE,_5,"\x1\xD8",
0,FPUREG,NONE,PLUSREG,"\x2\xD8\xE8",
0,ST0,FPUREG,PLUSREG,"\x2\xD8\xE8",
0,FPUREG,ST0,PLUSREG,"\x2\xDC\xE0",
"fsubp",FPUREG,NONE,PLUSREG,"\x2\xDE\xE8",
0,FPUREG,ST0,PLUSREG,"\x2\xDE\xE8",
"fsubrp",FPUREG,NONE,PLUSREG,"\x2\xDE\xE0",
0,FPUREG,ST0,PLUSREG,"\x2\xDE\xE0",
"ftst",NONE,NONE,0,"\x2\xD9\xE4",
"fucom",FPUREG,NONE,PLUSREG,"\x2\xDD\xE0",
0,ST0,FPUREG,PLUSREG,"\x2\xDD\xE0",
"fucomp",FPUREG,NONE,PLUSREG,"\x2\xDD\xE8",
0,ST0,FPUREG,PLUSREG,"\x2\xDD\xE8",
"fucompp",NONE,NONE,0,"\x2\xDA\xE9",
"fucomi",FPUREG,NONE,PLUSREG,"\x2\xDB\xE8",
0,ST0,FPUREG,PLUSREG,"\x2\xDB\xE8",
"fucomip",FPUREG,NONE,PLUSREG,"\x2\xDF\xE8",
0,ST0,FPUREG,PLUSREG,"\x2\xDF\xE8",
"fxam",NONE,NONE,0,"\x2\xD9\xE5",
"fxch",NONE,NONE,0,"\x2\xD9\xC9",
0,FPUREG,NONE,PLUSREG,"\x2\xD9\xC8",
0,FPUREG,ST0,PLUSREG,"\x2\xD9\xC8",
0,ST0,FPUREG,PLUSREG,"\x2\xD9\xC8",
"fxtract",NONE,NONE,0,"\x2\xD9\xF4",
"fyl2x",NONE,NONE,0,"\x2\xD9\xF1",
"fyl2xp1",NONE,NONE,0,"\x2\xD9\xF9",
"hlt",NONE,NONE,0,"\x1\xF4",
"ibts",R_M16,REG16,O16|_R,"\x2\x0F\xA7",
0,R_M32,REG32,O32|_R,"\x2\x0F\xA7",
"idiv",R_M8,NONE,_7,"\x1\xF6",
0,R_M16,NONE,O16|_7,"\x1\xF7",
0,R_M32,NONE,O32|_7,"\x1\xF7",
"imul",R_M8,NONE,_5,"\x1\xF6",
0,R_M16,NONE,O16|_5,"\x1\xF7",
0,R_M32,NONE,O32|_5,"\x1\xF7",
0,REG16,R_M16,O16|_R,"\x2\x0F\xAF",
0,REG32,R_M32,O32|_R,"\x2\x0F\xAF",
0,REG16,IMM8,O16|_R|IB,"\x1\x6B",
0,REG16,IMM16,O16|_R|IW,"\x1\x69",
0,REG32,IMM8,O32|_R|IB,"\x1\x6B",
0,REG32,IMM32,O32|_R|ID,"\x1\x69",
"in",AL,IMM8,IB,"\x1\xE4",
0,AX,IMM8,O16|IB,"\x1\xE5",
0,EAX,IMM8,O32|IB,"\x1\xE5",
"inc",REG16,NONE,O16|PLUSREG,"\x1\x40",
0,REG32,NONE,O32|PLUSREG,"\x1\x40",
0,R_M8,NONE,_0,"\x1\xFE",
0,R_M16,NONE,O16|_0,"\x1\xFF",
0,R_M32,NONE,O32|_0,"\x1\xFF",
"insb",NONE,NONE,0,"\x1\x6C",
"insw",NONE,NONE,O16,"\x1\x6D",
"insd",NONE,NONE,O32,"\x1\x6D",
"int",IMM8,NONE,IB,"\x1\xCD",
"int1",NONE,NONE,0,"\x1\xF1",
"icebp",NONE,NONE,0,"\x1\xF1",
"int01",NONE,NONE,0,"\x1\xF1",
"int3",NONE,NONE,0,"\x1\xCC",
"into",NONE,NONE,0,"\x1\xCE",
"invd",NONE,NONE,0,"\x2\x0F\x08",
"invlpg",MEM,NONE,_0,"\x2\x0F\x01",
"iret",NONE,NONE,0,"\x1\xCF",
"iretw",NONE,NONE,O16,"\x1\xCF",
"iretd",NONE,NONE,O32,"\x1\xCF",
"jmp",IMM,NONE,RW_RD,"\x1\xE9",
0,R_M16,NONE,O16|_4,"\x1\xFF",
0,R_M32,NONE,O32|_4,"\x1\xFF",
"lahf",NONE,NONE,0,"\x1\x9F",
"lar",REG16,R_M16,O16|_R,"\x2\x0F\x02",
0,REG32,R_M32,O32|_R,"\x2\x0F\x02",
"lds",REG16,MEM,O16|_R,"\x1\xC5",
0,REG32,MEM,O32|_R,"\x1\xC5",
"les",REG16,MEM,O16|_R,"\x1\xC4",
0,REG32,MEM,O32|_R,"\x1\xC4",
"lfs",REG16,MEM,O16|_R,"\x2\x0F\xB4",
0,REG32,MEM,O32|_R,"\x2\x0F\xB4",
"lgs",REG16,MEM,O16|_R,"\x2\x0F\xB5",
0,REG32,MEM,O32|_R,"\x2\x0F\xB5",
"lss",REG16,MEM,O16|_R,"\x2\x0F\xB2",
0,REG32,MEM,O32|_R,"\x2\x0F\xB2",
"lea",REG16,MEM,O16|_R,"\x1\x8D",
0,REG32,MEM,O32|_R,"\x1\x8D",
"leave",NONE,NONE,0,"\x1\xC9",
"lgdt",MEM,NONE,_2,"\x2\x0F\x01",
"lidt",MEM,NONE,_3,"\x2\x0F\x01",
"lldt",R_M16,NONE,_2,"\x2\x0F\x00",
"lmsw",R_M16,NONE,_6,"\x2\x0F\x01",
"loadall",NONE,NONE,0,"\x2\x0F\x07",
"loadall286",NONE,NONE,0,"\x2\x0F\x05",
"lodsb",NONE,NONE,0,"\x1\xAC",
"lodsw",NONE,NONE,O16,"\x1\xAD",
"lodsd",NONE,NONE,O32,"\x1\xAD",
"lsl",REG16,R_M16,O16|_R,"\x2\x0F\x03",
0,REG32,R_M32,O32|_R,"\x2\x0F\x03",
"ltr",R_M16,NONE,_3,"\x2\x0F\x00",
"mov",R_M8,REG8,_R,"\x1\x88",
0,R_M16,REG16,O16|_R,"\x1\x89",
0,R_M32,REG32,O32|_R,"\x1\x89",
0,REG8,R_M8,_R,"\x1\x8A",
0,REG16,R_M16,O16|_R,"\x1\x8B",
0,REG32,R_M32,O32|_R,"\x1\x8B",
0,REG8,IMM8,PLUSREG|IB,"\x1\xB0",
0,REG16,IMM16,O16|PLUSREG|IW,"\x1\xB8",
0,REG32,IMM32,O32|PLUSREG|ID,"\x1\xB8",
0,R_M8,IMM8,_0|IB,"\x1\xC6",
0,R_M16,IMM16,O16|_0|IW,"\x1\xC7",
0,R_M32,IMM32,O32|_0|ID,"\x1\xC7",
"movsb",NONE,NONE,0,"\x1\xA4",
"movsw",NONE,NONE,O16,"\x1\xA5",
"movsd",NONE,NONE,O32,"\x1\xA5",
"movsx",REG16,R_M8,O16|_R,"\x2\x0F\xBE",
0,REG32,R_M8,O32|_R,"\x2\x0F\xBE",
0,REG32,R_M16,O32|_R,"\x2\x0F\xBF",
"movzx",REG16,R_M8,O16|_R,"\x2\x0F\xB6",
0,REG32,R_M8,O32|_R,"\x2\x0F\xB6",
0,REG32,R_M16,O32|_R,"\x2\x0F\xB7",
"mul",R_M8,NONE,_4,"\x1\xF6",
0,R_M16,NONE,O16|_4,"\x1\xF7",
0,R_M32,NONE,O32|_4,"\x1\xF7",
"neg",R_M8,NONE,_3,"\x1\xF6",
0,R_M16,NONE,O16|_3,"\x1\xF7",
0,R_M32,NONE,O32|_3,"\x1\xF7",
"not",R_M8,NONE,_2,"\x1\xF6",
0,R_M16,NONE,O16|_2,"\x1\xF7",
0,R_M32,NONE,O32|_2,"\x1\xF7",
"nop",NONE,NONE,0,"\x1\x90",
"or",AL,IMM8,IB,"\x1\x0C",
0,AX,IMM16,O16|IW,"\x1\x0D",
0,EAX,IMM32,O32|ID,"\x1\x0D",
0,R_M8,REG8,_R,"\x1\x08",
0,R_M16,REG16,O16|_R,"\x1\x09",
0,R_M32,REG32,O32|_R,"\x1\x09",
0,REG8,R_M8,_R,"\x1\x0A",
0,REG16,R_M16,O16|_R,"\x1\x0B",
0,REG32,R_M32,O32|_R,"\x1\x0B",
0,R_M8,IMM8,_1|IB,"\x1\x80",
0,R_M16,IMM16,O16|_1|IW,"\x1\x81",
0,R_M32,IMM32,O32|_1|ID,"\x1\x81",
0,R_M16,IMM8,O16|_1|IB,"\x1\x83",
0,R_M32,IMM8,O32|_1|IB,"\x1\x83",
"out",IMM8,AL,IB,"\x1\xE6",
0,IMM8,AX,O16|IB,"\x1\xE7",
0,IMM8,EAX,O32|IB,"\x1\xE7",
"outsb",NONE,NONE,0,"\x1\x6E",
"outsw",NONE,NONE,O16,"\x1\x6F",
"outsd",NONE,NONE,O32,"\x1\x6F",
"pop",REG16,NONE,O16|PLUSREG,"\x1\x58",
0,REG32,NONE,O32|PLUSREG,"\x1\x58",
0,R_M16,NONE,O16|_0,"\x1\x8F",
0,R_M32,NONE,O32|_0,"\x1\x8F",
"popa",NONE,NONE,0,"\x1\x61",
"popaw",NONE,NONE,O16,"\x1\x61",
"popad",NONE,NONE,O32,"\x1\x61",
"popf",NONE,NONE,0,"\x1\x9D",
"popfw",NONE,NONE,O16,"\x1\x9D",
"popfd",NONE,NONE,O32,"\x1\x9D",
"push",REG16,NONE,O16|PLUSREG,"\x1\x50",
0,REG32,NONE,O32|PLUSREG,"\x1\x50",
0,R_M16,NONE,O16|_6,"\x1\xFF",
0,R_M32,NONE,O32|_6,"\x1\xFF",
0,IMM8,NONE,IB,"\x1\x6A",
0,IMM16,NONE,O16|IW,"\x1\x68",
0,IMM32,NONE,O32|ID,"\x1\x68",
"pusha",NONE,NONE,0,"\x1\x60",
"pushad",NONE,NONE,O32,"\x1\x60",
"pushaw",NONE,NONE,O16,"\x1\x60",
"pushf",NONE,NONE,0,"\x1\x9C",
"pushfd",NONE,NONE,O32,"\x1\x9C",
"pushfw",NONE,NONE,O16,"\x1\x9C",
"rcl",R_M8,CL,_2,"\x1\xD2",
0,R_M8,IMM8,_2|IB,"\x1\xC0",
0,R_M16,CL,O16|_2,"\x1\xD3",
0,R_M16,IMM8,O16|_2|IB,"\x1\xC1",
0,R_M32,CL,O32|_2,"\x1\xD3",
0,R_M32,IMM8,O32|_2|IB,"\x1\xC1",
"rcr",R_M8,CL,_3,"\x1\xD2",
0,R_M8,IMM8,_3|IB,"\x1\xC0",
0,R_M16,CL,O16|_3,"\x1\xD3",
0,R_M16,IMM8,O16|_3|IB,"\x1\xC1",
0,R_M32,CL,O32|_3,"\x1\xD3",
0,R_M32,IMM8,O32|_3|IB,"\x1\xC1",
"rdmsr",NONE,NONE,0,"\x2\x0F\x32",
"rdpmc",NONE,NONE,0,"\x2\x0F\x33",
"rdtsc",NONE,NONE,0,"\x2\x0F\x31",
"ret",NONE,NONE,0,"\x1\xC3",
0,IMM16,NONE,IW,"\x1\xC2",
"retf",NONE,NONE,0,"\x1\xCB",
0,IMM16,NONE,IW,"\x1\xCA",
"retn",NONE,NONE,0,"\x1\xC3",
0,IMM16,NONE,IW,"\x1\xC2",
"rol",R_M8,CL,_0,"\x1\xD2",
0,R_M8,IMM8,_0|IB,"\x1\xC0",
0,R_M16,CL,O16|_0,"\x1\xD3",
0,R_M16,IMM8,O16|_0|IB,"\x1\xC1",
0,R_M32,CL,O32|_0,"\x1\xD3",
0,R_M32,IMM8,O32|_0|IB,"\x1\xC1",
"ror",R_M8,CL,_1,"\x1\xD2",
0,R_M8,IMM8,_1|IB,"\x1\xC0",
0,R_M16,CL,O16|_1,"\x1\xD3",
0,R_M16,IMM8,O16|_1|IB,"\x1\xC1",
0,R_M32,CL,O32|_1,"\x1\xD3",
0,R_M32,IMM8,O32|_1|IB,"\x1\xC1",
"rsm",NONE,NONE,0,"\x2\x0F\xAA",
"sahf",NONE,NONE,0,"\x1\x9E",
"sal",R_M8,CL,_4,"\x1\xD2",
0,R_M8,IMM8,_4|IB,"\x1\xC0",
0,R_M16,CL,O16|_4,"\x1\xD3",
0,R_M16,IMM8,O16|_4|IB,"\x1\xC1",
0,R_M32,CL,O32|_4,"\x1\xD3",
0,R_M32,IMM8,O32|_4|IB,"\x1\xC1",
"sar",R_M8,CL,_7,"\x1\xD2",
0,R_M8,IMM8,_7|IB,"\x1\xC0",
0,R_M16,CL,O16|_7,"\x1\xD3",
0,R_M16,IMM8,O16|_7|IB,"\x1\xC1",
0,R_M32,CL,O32|_7,"\x1\xD3",
0,R_M32,IMM8,O32|_7|IB,"\x1\xC1",
"salc",NONE,NONE,0,"\x1\xD6",
"sbb",AL,IMM8,IB,"\x1\x1C",
0,AX,IMM16,O16|IW,"\x1\x1D",
0,EAX,IMM32,O32|ID,"\x1\x1D",
0,R_M8,REG8,_R,"\x1\x18",
0,R_M16,REG16,O16|_R,"\x1\x19",
0,R_M32,REG32,O32|_R,"\x1\x19",
0,REG8,R_M8,_R,"\x1\x1A",
0,REG16,R_M16,O16|_R,"\x1\x1B",
0,REG32,R_M32,O32|_R,"\x1\x1B",
0,R_M8,IMM8,_3|IB,"\x1\x80",
0,R_M16,IMM16,O16|_3|IW,"\x1\x81",
0,R_M32,IMM32,O32|_3|ID,"\x1\x81",
0,R_M16,IMM8,O16|_3|IB,"\x1\x83",
0,R_M32,IMM8,O32|_3|IB,"\x1\x83",
"scasb",NONE,NONE,0,"\x1\xAE",
"scasw",NONE,NONE,O16,"\x1\xAF",
"scasd",NONE,NONE,O32,"\x1\xAF",
"sgdt",MEM,NONE,_0,"\x2\x0F\x01",
"sidt",MEM,NONE,_1,"\x2\x0F\x01",
"sldt",R_M16,NONE,_0,"\x2\x0F\x00",
"shl",R_M8,CL,_4,"\x1\xD2",
0,R_M8,IMM8,_4|IB,"\x1\xC0",
0,R_M16,CL,O16|_4,"\x1\xD3",
0,R_M16,IMM8,O16|_4|IB,"\x1\xC1",
0,R_M32,CL,O32|_4,"\x1\xD3",
0,R_M32,IMM8,O32|_4|IB,"\x1\xC1",
"shr",R_M8,CL,_5,"\x1\xD2",
0,R_M8,IMM8,_5|IB,"\x1\xC0",
0,R_M16,CL,O16|_5,"\x1\xD3",
0,R_M16,IMM8,O16|_5|IB,"\x1\xC1",
0,R_M32,CL,O32|_5,"\x1\xD3",
0,R_M32,IMM8,O32|_5|IB,"\x1\xC1",
"smi",NONE,NONE,0,"\x1\xF1",
"smsw",R_M16,NONE,_4,"\x2\x0F\x01",
"stc",NONE,NONE,0,"\x1\xF9",
"std",NONE,NONE,0,"\x1\xFD",
"sti",NONE,NONE,0,"\x1\xFB",
"stosb",NONE,NONE,0,"\x1\xAA",
"stosw",NONE,NONE,O16,"\x1\xAB",
"stosd",NONE,NONE,O32,"\x1\xAB",
"str",R_M16,NONE,_1,"\x2\x0F\x00",
"sub",AL,IMM8,IB,"\x1\x2C",
0,AX,IMM16,O16|IW,"\x1\x2D",
0,EAX,IMM32,O32|ID,"\x1\x2D",
0,R_M8,REG8,_R,"\x1\x28",
0,R_M16,REG16,O16|_R,"\x1\x29",
0,R_M32,REG32,O32|_R,"\x1\x29",
0,REG8,R_M8,_R,"\x1\x2A",
0,REG16,R_M16,O16|_R,"\x1\x2B",
0,REG32,R_M32,O32|_R,"\x1\x2B",
0,R_M8,IMM8,_5|IB,"\x1\x80",
0,R_M16,IMM16,O16|_5|IW,"\x1\x81",
0,R_M32,IMM32,O32|_5|ID,"\x1\x81",
0,R_M16,IMM8,O16|_5|IB,"\x1\x83",
0,R_M32,IMM8,O32|_5|IB,"\x1\x83",
"test",AL,IMM8,IB,"\x1\xA8",
0,AX,IMM16,O16|IW,"\x1\xA9",
0,EAX,IMM32,O32|ID,"\x1\xA9",
0,R_M8,REG8,_R,"\x1\x84",
0,R_M16,REG16,O16|_R,"\x1\x85",
0,R_M32,REG32,O32|_R,"\x1\x85",
0,R_M8,IMM8,_7|IB,"\x1\xF6",
0,R_M16,IMM16,O16|_7|IW,"\x1\xF7",
0,R_M32,IMM32,O32|_7|ID,"\x1\xF7",
"umov",R_M8,REG8,_R,"\x2\x0F\x10",
0,R_M16,REG16,O16|_R,"\x2\x0F\x11",
0,R_M32,REG32,O32|_R,"\x2\x0F\x11",
0,REG8,R_M8,_R,"\x2\x0F\x12",
0,REG16,R_M16,O16|_R,"\x2\x0F\x13",
0,REG32,R_M32,O32|_R,"\x2\x0F\x13",
"verr",R_M16,NONE,_4,"\x2\x0F\x00",
"verw",R_M16,NONE,_5,"\x2\x0F\x00",
"wait",NONE,NONE,0,"\x1\x9B",
"wbinvd",NONE,NONE,0,"\x2\x0F\x09",
"wrmsr",NONE,NONE,0,"\x2\x0F\x30",
"xadd",R_M8,REG8,_R,"\x2\x0F\xC0",
0,R_M16,REG16,O16|_R,"\x2\x0F\xC1",
0,R_M32,REG32,O32|_R,"\x2\x0F\xC1",
"xbts",REG16,R_M16,O16|_R,"\x2\x0F\xA6",
0,REG32,R_M32,O32|_R,"\x2\x0F\xA6",
"xchg",REG8,R_M8,_R,"\x1\x86",
0,REG16,R_M8,O16|_R,"\x1\x87",
0,REG32,R_M32,O32|_R,"\x1\x87",
0,R_M8,REG8,_R,"\x1\x86",
0,R_M16,REG16,O16|_R,"\x1\x87",
0,R_M32,REG32,O32|_R,"\x1\x87",
0,AX,REG16,O16|PLUSREG,"\x1\x90",
0,EAX,REG32,O32|PLUSREG,"\x1\x90",
0,REG16,AX,O16|PLUSREG,"\x1\x90",
0,REG32,EAX,O32|PLUSREG,"\x1\x90",
"xlatb",NONE,NONE,0,"\x1\xD7",
"xor",AL,IMM8,IB,"\x1\x34",
0,AX,IMM16,O16|IW,"\x1\x35",
0,EAX,IMM32,O32|ID,"\x1\x35",
0,R_M8,REG8,_R,"\x1\x30",
0,R_M16,REG16,O16|_R,"\x1\x31",
0,R_M32,REG32,O32|_R,"\x1\x31",
0,REG8,R_M8,_R,"\x1\x32",
0,REG16,R_M16,O16|_R,"\x1\x33",
0,REG32,R_M32,O32|_R,"\x1\x33",
0,R_M8,IMM8,_6|IB,"\x1\x80",
0,R_M16,IMM16,O16|_6|IW,"\x1\x81",
0,R_M32,IMM32,O32|_6|ID,"\x1\x81",
0,R_M16,IMM8,O16|_6|IB,"\x1\x83",
0,R_M32,IMM8,O32|_6|IB,"\x1\x83",
"",0,0,0,0
};
@@ -1,7 +1,4 @@
#pragma once
#ifndef INSTS_H
#define INSTS_H
//operand addressing modes //operand addressing modes
enum{ enum{
REG=0x0001,REG8=0x0002,REG16=0x0004,REG32=0x0008, REG=0x0001,REG8=0x0002,REG16=0x0004,REG32=0x0008,
@@ -33,5 +30,3 @@ struct Inst{
}; };
extern Inst insts[]; extern Inst insts[];
#endif
@@ -1,25 +1,25 @@
#include "operand.hpp"
#include "operand.h" #include "../ex.hpp"
#include "../ex.h" #include "insts.hpp"
#include "../std.h"
#include "insts.h"
static const char* regs[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", "ax", "cx", "dx", "bx", static const char* regs[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", "ax", "cx", "dx", "bx",
"sp", "bp", "si", "di", "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"}; "sp", "bp", "si", "di", "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
static void opError() static void opError()
{ {
throw Ex("error in operand"); throw BlitzException("error in operand");
} }
static void sizeError() static void sizeError()
{ {
throw Ex("illegal operand size"); throw BlitzException("illegal operand size");
} }
Operand::Operand() : mode(NONE), reg(-1), imm(0), offset(0), baseReg(-1), indexReg(-1), shift(0) {} Operand::Operand() : mode(NONE), reg(-1), imm(0), offset(0), baseReg(-1), indexReg(-1), shift(0) {}
Operand::Operand(const string& s) : mode(NONE), reg(-1), imm(0), offset(0), baseReg(-1), indexReg(-1), shift(0), s(s) {} Operand::Operand(const std::string& s)
: mode(NONE), reg(-1), imm(0), offset(0), baseReg(-1), indexReg(-1), shift(0), s(s)
{}
bool Operand::parseSize(int* sz) bool Operand::parseSize(int* sz)
{ {
@@ -55,7 +55,7 @@ bool Operand::parseReg(int* reg)
} }
if (!i) if (!i)
return false; return false;
string t = s.substr(0, i); std::string t = s.substr(0, i);
for (int j = 0; j < 24; ++j) { for (int j = 0; j < 24; ++j) {
if (t == regs[j]) { if (t == regs[j]) {
*reg = j; *reg = j;
@@ -80,7 +80,7 @@ bool Operand::parseFPReg(int* reg)
return true; return true;
} }
bool Operand::parseLabel(string* label) bool Operand::parseLabel(std::string* label)
{ {
if (!s.size() || (!isalpha(s[0]) && s[0] != '_')) if (!s.size() || (!isalpha(s[0]) && s[0] != '_'))
return false; return false;
@@ -181,11 +181,11 @@ void Operand::parse()
mode |= MEM32 | R_M32; mode |= MEM32 | R_M32;
for (;;) { for (;;) {
int n; int n;
string l; std::string l;
if (parseReg(&n)) { if (parseReg(&n)) {
if (n < 16) if (n < 16)
throw Ex("register must be 32 bit"); throw BlitzException("register must be 32 bit");
n &= 7; n &= 7;
if (parseChar('*')) { if (parseChar('*')) {
if (n == 4) if (n == 4)
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include <iostream>
#include <string>
struct Operand {
int mode;
int reg, imm, offset;
std::string immLabel, baseLabel;
int baseReg, indexReg, shift;
Operand();
Operand(const std::string& s);
void parse();
private:
std::string s;
bool parseSize(int* sz);
bool parseChar(char c);
bool parseReg(int* reg);
bool parseFPReg(int* reg);
bool parseLabel(std::string* t);
bool parseConst(int* iconst);
};
@@ -1,8 +1,6 @@
#pragma once
#ifndef CODEGEN_H #include <string>
#define CODEGEN_H #include <ostream>
#include "std.hpp"
enum { enum {
IR_JUMP, IR_JUMP,
@@ -62,11 +60,11 @@ struct TNode {
int op; //opcode int op; //opcode
TNode *l, *r; //args TNode *l, *r; //args
int iconst; //for CONST type_int int iconst; //for CONST type_int
string sconst; //for CONST type_string std::string sconst; //for CONST type_string
TNode(int op, TNode* l = 0, TNode* r = 0) : op(op), l(l), r(r), iconst(0) {} TNode(int op, TNode* l = 0, TNode* r = 0) : op(op), l(l), r(r), iconst(0) {}
TNode(int op, TNode* l, TNode* r, int i) : op(op), l(l), r(r), iconst(i) {} TNode(int op, TNode* l, TNode* r, int i) : op(op), l(l), r(r), iconst(i) {}
TNode(int op, TNode* l, TNode* r, const string& s) : op(op), l(l), r(r), iconst(0), sconst(s) {} TNode(int op, TNode* l, TNode* r, const std::string& s) : op(op), l(l), r(r), iconst(0), sconst(s) {}
~TNode() ~TNode()
{ {
delete l; delete l;
@@ -78,19 +76,17 @@ struct TNode {
class Codegen { class Codegen {
public: public:
ostream& out; std::ostream& out;
bool debug; bool debug;
Codegen(ostream& out, bool debug) : out(out), debug(debug) {} Codegen(std::ostream& out, bool debug) : out(out), debug(debug) {}
virtual void enter(const string& l, int frameSize) = 0; virtual void enter(const std::string& l, int frameSize) = 0;
virtual void code(TNode* code) = 0; virtual void code(TNode* code) = 0;
virtual void leave(TNode* cleanup, int pop_sz) = 0; virtual void leave(TNode* cleanup, int pop_sz) = 0;
virtual void label(const string& l) = 0; virtual void label(const std::string& l) = 0;
virtual void i_data(int i, const string& l = "") = 0; virtual void i_data(int i, const std::string& l = "") = 0;
virtual void s_data(const string& s, const string& l = "") = 0; virtual void s_data(const std::string& s, const std::string& l = "") = 0;
virtual void p_data(const string& p, const string& l = "") = 0; virtual void p_data(const std::string& p, const std::string& l = "") = 0;
virtual void align_data(int n) = 0; virtual void align_data(int n) = 0;
virtual void flush() = 0; virtual void flush() = 0;
}; };
#endif
@@ -1,13 +1,135 @@
#include "codegen_x86.hpp"
#include "tile.hpp"
#include <string>
#include <vector>
#include "codegen_x86.h" #include <stdutil.hpp>
#include "../std.h"
#include "tile.h"
//#define NOOPTS //#define NOOPTS
Codegen_x86::Codegen_x86(ostream& out, bool debug) : Codegen(out, debug), inCode(false) {} Codegen_x86::Codegen_x86(std::ostream& out, bool debug) : Codegen(out, debug), inCode(false) {}
static string itoa_sgn(int n) void Codegen_x86::enter(const std::string& l, int frameSize)
{
inCode = true;
::frameSize = maxFrameSize = frameSize;
codeFrags.clear();
funcLabel = l;
}
void Codegen_x86::code(TNode* stmt)
{
resetRegs();
Tile* q = munch(stmt);
q->label();
q->eval(0);
delete q;
delete stmt;
}
void Codegen_x86::leave(TNode* cleanup, int pop_sz)
{
if (cleanup) {
resetRegs();
allocReg(EAX);
Tile* q = munch(cleanup);
q->label();
q->eval(0);
delete q;
}
out << "\t.align\t16\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';
int esp_off = 0;
std::vector<std::string>::iterator it = codeFrags.begin();
for (it = codeFrags.begin(); it != codeFrags.end(); ++it) {
const std::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;
}
out << *it;
}
}
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";
delete cleanup;
inCode = false;
}
void Codegen_x86::label(const std::string& l)
{
std::string t = l + '\n';
if (inCode)
codeFrags.push_back(t);
else
dataFrags.push_back(t);
}
void Codegen_x86::i_data(int i, const std::string& l)
{
if (l.size())
dataFrags.push_back(l);
char buff[32];
_itoa(i, buff, 10);
dataFrags.push_back(std::string("\t.dd\t") + buff + '\n');
}
void Codegen_x86::s_data(const std::string& s, const std::string& l)
{
if (l.size())
dataFrags.push_back(l);
dataFrags.push_back(std::string("\t.db\t\"") + s + "\",0\n");
}
void Codegen_x86::p_data(const std::string& p, const std::string& l)
{
if (l.size())
dataFrags.push_back(l);
dataFrags.push_back(std::string("\t.dd\t") + p + '\n');
}
void Codegen_x86::align_data(int n)
{
char buff[32];
_itoa(n, buff, 10);
dataFrags.push_back(std::string("\t.align\t") + buff + '\n');
}
void Codegen_x86::flush()
{
std::vector<std::string>::iterator it;
for (it = dataFrags.begin(); it != dataFrags.end(); ++it)
out << *it;
dataFrags.clear();
}
static std::string itoa_sgn(int n)
{ {
return n ? (n > 0 ? "+" + itoa(n) : itoa(n)) : ""; return n ? (n > 0 ? "+" + itoa(n) : itoa(n)) : "";
} }
@@ -50,7 +172,7 @@ static bool getShift(int n, int& shift)
return false; return false;
} }
static bool matchMEM(TNode* t, string& s) static bool matchMEM(TNode* t, std::string& s)
{ {
#ifdef NOOPTS #ifdef NOOPTS
return false; return false;
@@ -73,7 +195,7 @@ static bool matchMEM(TNode* t, string& s)
return false; return false;
} }
static bool matchCONST(TNode* t, string& s) static bool matchCONST(TNode* t, std::string& s)
{ {
#ifdef NOOPTS #ifdef NOOPTS
return false; return false;
@@ -90,7 +212,7 @@ static bool matchCONST(TNode* t, string& s)
return false; return false;
} }
static bool matchMEMCONST(TNode* t, string& s) static bool matchMEMCONST(TNode* t, std::string& s)
{ {
#ifdef NOOPTS #ifdef NOOPTS
return false; return false;
@@ -99,7 +221,7 @@ static bool matchMEMCONST(TNode* t, string& s)
return matchMEM(t, s) || matchCONST(t, s); return matchMEM(t, s) || matchCONST(t, s);
} }
Tile* Codegen_x86::genCompare(TNode* t, string& func, bool negate) Tile* Codegen_x86::genCompare(TNode* t, std::string& func, bool negate)
{ {
switch (t->op) { switch (t->op) {
case IR_SETEQ: case IR_SETEQ:
@@ -124,7 +246,7 @@ Tile* Codegen_x86::genCompare(TNode* t, string& func, bool negate)
return 0; return 0;
} }
string q, m, c; std::string q, m, c;
TNode *ql = 0, *qr = 0; TNode *ql = 0, *qr = 0;
if (matchMEM(t->l, m)) { if (matchMEM(t->l, m)) {
@@ -153,7 +275,7 @@ Tile* Codegen_x86::genCompare(TNode* t, string& func, bool negate)
//////////////////////////////////////////////// ////////////////////////////////////////////////
Tile* Codegen_x86::munchUnary(TNode* t) Tile* Codegen_x86::munchUnary(TNode* t)
{ {
string s; std::string s;
switch (t->op) { switch (t->op) {
case IR_NEG: case IR_NEG:
s = "\tneg\t%l\n"; s = "\tneg\t%l\n";
@@ -166,7 +288,7 @@ Tile* Codegen_x86::munchUnary(TNode* t)
Tile* Codegen_x86::munchLogical(TNode* t) Tile* Codegen_x86::munchLogical(TNode* t)
{ {
string s; std::string s;
switch (t->op) { switch (t->op) {
case IR_AND: case IR_AND:
s = "\tand\t%l,%r\n"; s = "\tand\t%l,%r\n";
@@ -212,7 +334,7 @@ Tile* Codegen_x86::munchArith(TNode* t)
} }
} }
string s, op; std::string s, op;
switch (t->op) { switch (t->op) {
case IR_ADD: case IR_ADD:
op = "\tadd\t"; op = "\tadd\t";
@@ -238,7 +360,7 @@ Tile* Codegen_x86::munchArith(TNode* t)
Tile* Codegen_x86::munchShift(TNode* t) Tile* Codegen_x86::munchShift(TNode* t)
{ {
string s, op; std::string s, op;
switch (t->op) { switch (t->op) {
case IR_SHL: case IR_SHL:
op = "\tshl\t"; op = "\tshl\t";
@@ -264,7 +386,7 @@ Tile* Codegen_x86::munchShift(TNode* t)
Tile* Codegen_x86::munchRelop(TNode* t) Tile* Codegen_x86::munchRelop(TNode* t)
{ {
string func; std::string func;
Tile* q = genCompare(t, func, false); Tile* q = genCompare(t, func, false);
q = new Tile("\tset" + func + "\tal\n\tmovzx\teax,al\n", q); q = new Tile("\tset" + func + "\tal\n\tmovzx\teax,al\n", q);
@@ -277,7 +399,7 @@ Tile* Codegen_x86::munchRelop(TNode* t)
//////////////////////////////////////////////// ////////////////////////////////////////////////
Tile* Codegen_x86::munchFPUnary(TNode* t) Tile* Codegen_x86::munchFPUnary(TNode* t)
{ {
string s; std::string s;
switch (t->op) { switch (t->op) {
case IR_FNEG: case IR_FNEG:
s = "\tfchs\n"; s = "\tfchs\n";
@@ -290,7 +412,7 @@ Tile* Codegen_x86::munchFPUnary(TNode* t)
Tile* Codegen_x86::munchFPArith(TNode* t) Tile* Codegen_x86::munchFPArith(TNode* t)
{ {
string s, s2; std::string s, s2;
switch (t->op) { switch (t->op) {
case IR_FADD: case IR_FADD:
s = "\tfaddp\tst(1)\n"; s = "\tfaddp\tst(1)\n";
@@ -314,7 +436,7 @@ Tile* Codegen_x86::munchFPArith(TNode* t)
Tile* Codegen_x86::munchFPRelop(TNode* t) Tile* Codegen_x86::munchFPRelop(TNode* t)
{ {
string s, s2; std::string s, s2;
switch (t->op) { switch (t->op) {
case IR_FSETEQ: case IR_FSETEQ:
s = "z"; s = "z";
@@ -375,7 +497,7 @@ Tile* Codegen_x86::munch(TNode* t)
if (!t) if (!t)
return 0; return 0;
Tile* q = 0; Tile* q = 0;
string s; std::string s;
switch (t->op) { switch (t->op) {
case IR_JSR: case IR_JSR:
q = new Tile("\tcall\t" + t->sconst + '\n'); q = new Tile("\tcall\t" + t->sconst + '\n');
@@ -404,7 +526,7 @@ Tile* Codegen_x86::munch(TNode* t)
if (TNode* p = t->l) { if (TNode* p = t->l) {
bool neg = false; bool neg = false;
if (isRelop(p->op)) { if (isRelop(p->op)) {
string func; std::string func;
q = genCompare(p, func, neg); q = genCompare(p, func, neg);
q = new Tile("\tj" + func + "\t" + t->sconst + "\n", q); q = new Tile("\tj" + func + "\t" + t->sconst + "\n", q);
} }
@@ -414,7 +536,7 @@ Tile* Codegen_x86::munch(TNode* t)
if (TNode* p = t->l) { if (TNode* p = t->l) {
bool neg = true; bool neg = true;
if (isRelop(p->op)) { if (isRelop(p->op)) {
string func; std::string func;
q = genCompare(p, func, neg); q = genCompare(p, func, neg);
q = new Tile("\tj" + func + "\t" + t->sconst + "\n", q); q = new Tile("\tj" + func + "\t" + t->sconst + "\n", q);
} }
@@ -422,7 +544,7 @@ Tile* Codegen_x86::munch(TNode* t)
break; break;
case IR_MOVE: case IR_MOVE:
if (matchMEM(t->r, s)) { if (matchMEM(t->r, s)) {
string c; std::string c;
if (matchCONST(t->l, c)) { if (matchCONST(t->l, c)) {
q = new Tile("\tmov\t" + s + "," + c + "\n"); q = new Tile("\tmov\t" + s + "," + c + "\n");
} else if (t->l->op == IR_ADD || t->l->op == IR_SUB) { } else if (t->l->op == IR_ADD || t->l->op == IR_SUB) {
@@ -432,7 +554,7 @@ Tile* Codegen_x86::munch(TNode* t)
else if (t->l->op == IR_ADD && nodesEqual(t->l->r, t->r)) else if (t->l->op == IR_ADD && nodesEqual(t->l->r, t->r))
p = t->l->l; p = t->l->l;
if (p) { if (p) {
string c, op; std::string c, op;
switch (t->l->op) { switch (t->l->op) {
case IR_ADD: case IR_ADD:
op = "\tadd\t"; op = "\tadd\t";
@@ -466,7 +588,7 @@ Tile* Codegen_x86::munchReg(TNode* t)
if (!t) if (!t)
return 0; return 0;
string s; std::string s;
Tile* q = 0; Tile* q = 0;
switch (t->op) { switch (t->op) {
@@ -507,7 +629,7 @@ Tile* Codegen_x86::munchReg(TNode* t)
q = new Tile("\tlea\t%l,[ebp" + itoa_sgn(t->iconst) + "]\n"); q = new Tile("\tlea\t%l,[ebp" + itoa_sgn(t->iconst) + "]\n");
break; break;
case IR_GLOBAL: case IR_GLOBAL:
q = new Tile(string("\tmov\t%l,") + t->sconst + '\n'); q = new Tile(std::string("\tmov\t%l,") + t->sconst + '\n');
break; break;
case IR_CAST: case IR_CAST:
q = munchFP(t->l); q = munchFP(t->l);
@@ -570,7 +692,7 @@ Tile* Codegen_x86::munchFP(TNode* t)
if (!t) if (!t)
return 0; return 0;
string s; std::string s;
Tile* q = 0; Tile* q = 0;
switch (t->op) { switch (t->op) {
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include "../codegen.hpp"
#include <ostream>
#include <string>
struct Tile;
class Codegen_x86 : public Codegen {
public:
Codegen_x86(std::ostream& out, bool debug);
virtual void enter(const std::string& l, int frameSize);
virtual void code(TNode* code);
virtual void leave(TNode* cleanup, int pop_sz);
virtual void label(const std::string& l);
virtual void i_data(int i, const std::string& l);
virtual void s_data(const std::string& s, const std::string& l);
virtual void p_data(const std::string& p, const std::string& l);
virtual void align_data(int n);
virtual void flush();
private:
bool inCode;
Tile* genCompare(TNode* t, std::string& func, bool negate);
Tile* munch(TNode* t); //munch and discard result
Tile* munchReg(TNode* t); //munch and put result in a CPU reg
Tile* munchFP(TNode* t); //munch and put result on FP stack
Tile* munchCall(TNode* t);
Tile* munchUnary(TNode* t);
Tile* munchLogical(TNode* t);
Tile* munchArith(TNode* t);
Tile* munchShift(TNode* t);
Tile* munchRelop(TNode* t);
Tile* munchFPUnary(TNode* t);
Tile* munchFPArith(TNode* t);
Tile* munchFPRelop(TNode* t);
};
@@ -1,32 +1,33 @@
#include "tile.hpp"
#include <string>
#include <vector>
#include "codegen_x86.hpp"
#include "tile.h" #include <stdutil.hpp>
#include "../std.h"
#include "codegen_x86.h"
//reduce to 3 for stress test //reduce to 3 for stress test
static const int NUM_REGS = 6;
static const string regs[] = {"???", "eax", "ecx", "edx", "edi", "esi", "ebx"}; const std::string regs[] = {"???", "eax", "ecx", "edx", "edi", "esi", "ebx"};
//array of 'used' flags //array of 'used' flags
static bool regUsed[NUM_REGS + 1]; bool regUsed[NUM_REGS + 1];
//size of locals in function //size of locals in function
static int frameSize, maxFrameSize; int frameSize, maxFrameSize;
//code fragments //code fragments
static vector<string> codeFrags, dataFrags; std::vector<std::string> codeFrags, dataFrags;
//name of function //name of function
static string funcLabel; std::string funcLabel;
static void resetRegs() void resetRegs()
{ {
for (int n = 1; n <= NUM_REGS; ++n) for (int n = 1; n <= NUM_REGS; ++n)
regUsed[n] = false; regUsed[n] = false;
} }
static int allocReg(int n) int allocReg(int n)
{ {
if (!n || regUsed[n]) { if (!n || regUsed[n]) {
for (n = NUM_REGS; n >= 1 && regUsed[n]; --n) { for (n = NUM_REGS; n >= 1 && regUsed[n]; --n) {
@@ -50,7 +51,7 @@ static void pushReg(int n)
maxFrameSize = frameSize; maxFrameSize = frameSize;
char buff[32]; char buff[32];
_itoa(frameSize, buff, 10); _itoa(frameSize, buff, 10);
string s = "\tmov\t[ebp-"; std::string s = "\tmov\t[ebp-";
s += buff; s += buff;
s += "],"; s += "],";
s += regs[n]; s += regs[n];
@@ -62,7 +63,7 @@ static void popReg(int n)
{ {
char buff[32]; char buff[32];
_itoa(frameSize, buff, 10); _itoa(frameSize, buff, 10);
string s = "\tmov\t"; std::string s = "\tmov\t";
s += regs[n]; s += regs[n];
s += ",[ebp-"; s += ",[ebp-";
s += buff; s += buff;
@@ -73,21 +74,21 @@ static void popReg(int n)
static void moveReg(int d, int s) static void moveReg(int d, int s)
{ {
string t = "\tmov\t" + regs[d] + ',' + regs[s] + '\n'; std::string t = "\tmov\t" + regs[d] + ',' + regs[s] + '\n';
codeFrags.push_back(t); codeFrags.push_back(t);
} }
static void swapRegs(int d, int s) static void swapRegs(int d, int s)
{ {
string t = "\txchg\t" + regs[d] + ',' + regs[s] + '\n'; std::string t = "\txchg\t" + regs[d] + ',' + regs[s] + '\n';
codeFrags.push_back(t); codeFrags.push_back(t);
} }
Tile::Tile(const string& a, Tile* l, Tile* r) Tile::Tile(const std::string& a, Tile* l, Tile* r)
: assem(a), l(l), r(r), want_l(0), want_r(0), hits(0), need(0), argFrame(0) : assem(a), l(l), r(r), want_l(0), want_r(0), hits(0), need(0), argFrame(0)
{} {}
Tile::Tile(const string& a, const string& a2, Tile* l, Tile* r) Tile::Tile(const std::string& a, const std::string& a2, Tile* l, Tile* r)
: assem(a), assem2(a2), l(l), r(r), want_l(0), want_r(0), hits(0), need(0), argFrame(0) : assem(a), assem2(a2), l(l), r(r), want_l(0), want_r(0), hits(0), need(0), argFrame(0)
{} {}
@@ -144,7 +145,7 @@ int Tile::eval(int want)
if (want_l) if (want_l)
want = want_l; want = want_l;
string* as = &assem; std::string* as = &assem;
if (!l) { if (!l) {
got_l = allocReg(want); got_l = allocReg(want);
@@ -186,9 +187,9 @@ int Tile::eval(int want)
moveReg(want_r, got_r); moveReg(want_r, got_r);
int i; int i;
while ((i = as->find("%l")) != string::npos) while ((i = as->find("%l")) != std::string::npos)
as->replace(i, 2, regs[want_l]); as->replace(i, 2, regs[want_l]);
while ((i = as->find("%r")) != string::npos) while ((i = as->find("%r")) != std::string::npos)
as->replace(i, 2, regs[want_r]); as->replace(i, 2, regs[want_r]);
codeFrags.push_back(*as); codeFrags.push_back(*as);
@@ -213,129 +214,9 @@ int Tile::eval(int want)
return got_l; return got_l;
} }
void Codegen_x86::flush() std::string fixEsp(int esp_off)
{
vector<string>::iterator it;
for (it = dataFrags.begin(); it != dataFrags.end(); ++it)
out << *it;
dataFrags.clear();
}
void Codegen_x86::enter(const string& l, int frameSize)
{
inCode = true;
::frameSize = maxFrameSize = frameSize;
codeFrags.clear();
funcLabel = l;
}
void Codegen_x86::code(TNode* stmt)
{
resetRegs();
Tile* q = munch(stmt);
q->label();
q->eval(0);
delete q;
delete stmt;
}
static string fixEsp(int esp_off)
{ {
if (esp_off < 0) if (esp_off < 0)
return "\tsub\tesp," + itoa(-esp_off) + "\n"; return "\tsub\tesp," + itoa(-esp_off) + "\n";
return "\tadd\tesp," + itoa(esp_off) + "\n"; return "\tadd\tesp," + itoa(esp_off) + "\n";
} }
void Codegen_x86::leave(TNode* cleanup, int pop_sz)
{
if (cleanup) {
resetRegs();
allocReg(EAX);
Tile* q = munch(cleanup);
q->label();
q->eval(0);
delete q;
}
out << "\t.align\t16\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';
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;
}
out << *it;
}
}
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";
delete cleanup;
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::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::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');
}
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include <string>
#include <vector>
enum { EAX = 1, ECX, EDX, EDI, ESI, EBX };
extern std::vector<std::string> codeFrags, dataFrags;
extern std::string funcLabel;
extern int frameSize, maxFrameSize;
const int NUM_REGS = 6;
extern bool regUsed[];
extern const std::string regs[];
extern void resetRegs();
extern int allocReg(int n);
extern std::string fixEsp(int esp_off);
struct Tile {
int want_l, want_r, hits, argFrame;
Tile(const std::string& a, Tile* l = 0, Tile* r = 0);
Tile(const std::string& a, const std::string& a2, Tile* l = 0, Tile* r = 0);
~Tile();
void label();
int eval(int want);
private:
int need;
Tile * l, *r;
std::string assem, assem2;
};
+10 -5
View File
@@ -1,8 +1,8 @@
#include "decl.hpp" #include "decl.hpp"
#include "std.hpp"
#include "type.hpp" #include "type.hpp"
Decl::Decl(const std::string& s, Type* t, int k, ConstType* d) : name(s), type(t), kind(k), defType(d) {}
Decl::~Decl() {} Decl::~Decl() {}
DeclSeq::DeclSeq() {} DeclSeq::DeclSeq() {}
@@ -20,9 +20,9 @@ DeclSeq::~DeclSeq()
delete decls.back(); delete decls.back();
} }
Decl* DeclSeq::findDecl(const string& s) Decl* DeclSeq::findDecl(const std::string& s)
{ {
vector<Decl*>::iterator it; std::vector<Decl*>::iterator it;
for (it = decls.begin(); it != decls.end(); ++it) { for (it = decls.begin(); it != decls.end(); ++it) {
if ((*it)->name == s) if ((*it)->name == s)
return *it; return *it;
@@ -30,10 +30,15 @@ Decl* DeclSeq::findDecl(const string& s)
return 0; return 0;
} }
Decl* DeclSeq::insertDecl(const string& s, Type* t, int kind, ConstType* d) Decl* DeclSeq::insertDecl(const std::string& s, Type* t, int kind, ConstType* d)
{ {
if (findDecl(s)) if (findDecl(s))
return 0; return 0;
decls.push_back(new Decl(s, t, kind, d)); decls.push_back(new Decl(s, t, kind, d));
return decls.back(); return decls.back();
} }
int DeclSeq::size()
{
return decls.size();
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include <string>
#include <vector>
enum {
DECL_FUNC = 1,
DECL_ARRAY = 2,
DECL_STRUCT = 4, //NOT vars
DECL_GLOBAL = 8,
DECL_LOCAL = 16,
DECL_PARAM = 32,
DECL_FIELD = 64 //ARE vars
};
struct Type;
struct ConstType;
struct Decl {
std::string name;
Type* type; //type
int kind, offset;
ConstType* defType; //default value
Decl(const std::string& s, Type* t, int k, ConstType* d = 0);
~Decl();
virtual void getName(char* buff);
};
struct DeclSeq {
std::vector<Decl*> decls;
DeclSeq();
~DeclSeq();
Decl* findDecl(const std::string& s);
Decl* insertDecl(const std::string& s, Type* t, int kind, ConstType* d = 0);
int size();
};
@@ -1,6 +1,22 @@
#include "decl.hpp"
#include "environ.hpp"
#include "ex.hpp"
#include "nodes.hpp" #include "nodes.hpp"
#include "std.hpp" #include "type.hpp"
#include "label.hpp"
#include "varnode.hpp"
#include "codegen.hpp"
#include <stdutil.hpp>
#include "declnode.hpp"
DeclSeqNode::DeclSeqNode() {}
DeclSeqNode::~DeclSeqNode()
{
for (; decls.size(); decls.pop_back())
delete decls.back();
}
////////////////////////////// //////////////////////////////
// Sequence of declarations // // Sequence of declarations //
@@ -10,7 +26,7 @@ void DeclSeqNode::proto(DeclSeq* d, Environ* e)
for (size_t k = 0; k < decls.size(); ++k) { for (size_t k = 0; k < decls.size(); ++k) {
try { try {
decls[k]->proto(d, e); decls[k]->proto(d, e);
} catch (Ex& x) { } catch (BlitzException& x) {
if (x.pos < 0) if (x.pos < 0)
x.pos = decls[k]->pos; x.pos = decls[k]->pos;
if (!x.file.size()) if (!x.file.size())
@@ -25,7 +41,7 @@ void DeclSeqNode::semant(Environ* e)
for (size_t k = 0; k < decls.size(); ++k) { for (size_t k = 0; k < decls.size(); ++k) {
try { try {
decls[k]->semant(e); decls[k]->semant(e);
} catch (Ex& x) { } catch (BlitzException& x) {
if (x.pos < 0) if (x.pos < 0)
x.pos = decls[k]->pos; x.pos = decls[k]->pos;
if (!x.file.size()) if (!x.file.size())
@@ -40,7 +56,7 @@ void DeclSeqNode::translate(Codegen* g)
for (size_t k = 0; k < decls.size(); ++k) { for (size_t k = 0; k < decls.size(); ++k) {
try { try {
decls[k]->translate(g); decls[k]->translate(g);
} catch (Ex& x) { } catch (BlitzException& x) {
if (x.pos < 0) if (x.pos < 0)
x.pos = decls[k]->pos; x.pos = decls[k]->pos;
if (!x.file.size()) if (!x.file.size())
@@ -55,7 +71,7 @@ void DeclSeqNode::transdata(Codegen* g)
for (size_t k = 0; k < decls.size(); ++k) { for (size_t k = 0; k < decls.size(); ++k) {
try { try {
decls[k]->transdata(g); decls[k]->transdata(g);
} catch (Ex& x) { } catch (BlitzException& x) {
if (x.pos < 0) if (x.pos < 0)
x.pos = decls[k]->pos; x.pos = decls[k]->pos;
if (!x.file.size()) if (!x.file.size())
@@ -65,6 +81,26 @@ void DeclSeqNode::transdata(Codegen* g)
} }
} }
void DeclSeqNode::push_back(DeclNode* d)
{
decls.push_back(d);
}
int DeclSeqNode::size()
{
return decls.size();
}
VarDeclNode::VarDeclNode(const std::string& i, const std::string& t, int k, bool c, ExprNode* e)
: ident(i), tag(t), kind(k), constant(c), expr(e), sem_var(0)
{}
VarDeclNode::~VarDeclNode()
{
delete expr;
delete sem_var;
}
//////////////////////////// ////////////////////////////
// Simple var declaration // // Simple var declaration //
//////////////////////////// ////////////////////////////
@@ -131,6 +167,16 @@ void VarDeclNode::translate(Codegen* g)
g->code(sem_var->store(g, expr->translate(g))); g->code(sem_var->store(g, expr->translate(g)));
} }
FuncDeclNode::FuncDeclNode(const std::string& i, const std::string& t, DeclSeqNode* p, StmtSeqNode* ss)
: ident(i), tag(t), params(p), stmts(ss)
{}
FuncDeclNode::~FuncDeclNode()
{
delete params;
delete stmts;
}
////////////////////////// //////////////////////////
// Function Declaration // // Function Declaration //
////////////////////////// //////////////////////////
@@ -177,7 +223,7 @@ void FuncDeclNode::translate(Codegen* g)
if (t) if (t)
g->code(t); g->code(t);
if (g->debug) { if (g->debug) {
string t = genLabel(); std::string t = genLabel();
g->s_data(ident, t); g->s_data(ident, t);
g->code(call("__bbDebugEnter", local(0), iconst((int)sem_env), global(t))); g->code(call("__bbDebugEnter", local(0), iconst((int)sem_env), global(t)));
} }
@@ -198,6 +244,13 @@ void FuncDeclNode::translate(Codegen* g)
g->leave(t, sem_type->params->size() * 4); g->leave(t, sem_type->params->size() * 4);
} }
StructDeclNode::StructDeclNode(const std::string& i, DeclSeqNode* f) : ident(i), fields(f) {}
StructDeclNode::~StructDeclNode()
{
delete fields;
}
////////////////////// //////////////////////
// Type Declaration // // Type Declaration //
////////////////////// //////////////////////
@@ -230,7 +283,7 @@ void StructDeclNode::translate(Codegen* g)
//used and free lists for type //used and free lists for type
int k; int k;
for (k = 0; k < 2; ++k) { for (k = 0; k < 2; ++k) {
string lab = genLabel(); std::string lab = genLabel();
g->i_data(0, lab); //fields g->i_data(0, lab); //fields
g->p_data(lab); //next g->p_data(lab); //next
g->p_data(lab); //prev g->p_data(lab); //prev
@@ -243,9 +296,9 @@ void StructDeclNode::translate(Codegen* g)
//type of each field //type of each field
for (k = 0; k < sem_type->fields->size(); ++k) { for (k = 0; k < sem_type->fields->size(); ++k) {
Decl* field = sem_type->fields->decls[k]; Decl* field = sem_type->fields->decls[k];
Type* type = field->type; Type* type = field->type;
string t; std::string t;
if (type == Type::int_type) if (type == Type::int_type)
t = "__bbIntType"; t = "__bbIntType";
else if (type == Type::float_type) else if (type == Type::float_type)
@@ -260,6 +313,13 @@ void StructDeclNode::translate(Codegen* g)
} }
} }
DataDeclNode::DataDeclNode(ExprNode* e) : expr(e) {}
DataDeclNode::~DataDeclNode()
{
delete expr;
}
////////////////////// //////////////////////
// Data declaration // // Data declaration //
////////////////////// //////////////////////
@@ -299,6 +359,15 @@ void DataDeclNode::transdata(Codegen* g)
} }
} }
VectorDeclNode::VectorDeclNode(const std::string& i, const std::string& t, ExprSeqNode* e, int k)
: ident(i), tag(t), exprs(e), kind(k)
{}
VectorDeclNode::~VectorDeclNode()
{
delete exprs;
}
//////////////////////// ////////////////////////
// Vector declaration // // Vector declaration //
//////////////////////// ////////////////////////
@@ -308,7 +377,7 @@ void VectorDeclNode::proto(DeclSeq* d, Environ* env)
if (!ty) if (!ty)
ty = Type::int_type; ty = Type::int_type;
vector<int> sizes; std::vector<int> sizes;
for (int k = 0; k < exprs->size(); ++k) { for (int k = 0; k < exprs->size(); ++k) {
ExprNode* e = exprs->exprs[k] = exprs->exprs[k]->semant(env); ExprNode* e = exprs->exprs[k] = exprs->exprs[k]->semant(env);
ConstNode* c = e->constNode(); ConstNode* c = e->constNode();
@@ -319,8 +388,8 @@ void VectorDeclNode::proto(DeclSeq* d, Environ* env)
ex("Blitz array sizes must not be negative"); ex("Blitz array sizes must not be negative");
sizes.push_back(n + 1); sizes.push_back(n + 1);
} }
string label = genLabel(); std::string label = genLabel();
sem_type = new VectorType(label, ty, sizes); sem_type = new VectorType(label, ty, sizes);
if (!d->insertDecl(ident, sem_type, kind)) { if (!d->insertDecl(ident, sem_type, kind)) {
delete sem_type; delete sem_type;
ex("Duplicate identifier"); ex("Duplicate identifier");
@@ -338,8 +407,8 @@ void VectorDeclNode::translate(Codegen* g)
for (size_t k = 0; k < v->sizes.size(); ++k) for (size_t k = 0; k < v->sizes.size(); ++k)
sz *= v->sizes[k]; sz *= v->sizes[k];
g->i_data(sz); g->i_data(sz);
string t; std::string t;
Type* type = v->elementType; Type* type = v->elementType;
if (type == Type::int_type) if (type == Type::int_type)
t = "__bbIntType"; t = "__bbIntType";
else if (type == Type::float_type) else if (type == Type::float_type)
@@ -355,3 +424,13 @@ void VectorDeclNode::translate(Codegen* g)
if (kind == DECL_GLOBAL) if (kind == DECL_GLOBAL)
g->i_data(0, "_v" + ident); g->i_data(0, "_v" + ident);
} }
DeclNode::DeclNode() : pos(-1) {}
void DeclNode::proto(DeclSeq* d, Environ* e) {}
void DeclNode::semant(Environ* e) {}
void DeclNode::translate(Codegen* g) {}
void DeclNode::transdata(Codegen* g) {}
+95
View File
@@ -0,0 +1,95 @@
#pragma once
#include <string>
#include <vector>
#include "node.hpp"
#include "type.hpp"
class Codegen;
class Environ;
struct StmtSeqNode;
struct DeclVarNode;
struct ExprNode;
struct ExprSeqNode;
struct DeclNode : public Node {
int pos;
std::string file;
DeclNode();
virtual void proto(DeclSeq* d, Environ* e);
virtual void semant(Environ* e);
virtual void translate(Codegen* g);
virtual void transdata(Codegen* g);
};
struct DeclSeqNode : public Node {
std::vector<DeclNode*> decls;
DeclSeqNode();
~DeclSeqNode();
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
void transdata(Codegen* g);
void push_back(DeclNode* d);
int size();
};
//'kind' shouldn't really be in Parser...
//should probably be LocalDeclNode,GlobalDeclNode,ParamDeclNode
struct VarDeclNode : public DeclNode {
std::string ident, tag;
int kind;
bool constant;
ExprNode* expr;
DeclVarNode* sem_var;
VarDeclNode(const std::string& i, const std::string& t, int k, bool c, ExprNode* e);
~VarDeclNode();
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
};
struct FuncDeclNode : public DeclNode {
std::string ident, tag;
DeclSeqNode* params;
StmtSeqNode* stmts;
FuncType* sem_type;
Environ* sem_env;
FuncDeclNode(const std::string& i, const std::string& t, DeclSeqNode* p, StmtSeqNode* ss);
~FuncDeclNode();
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
};
struct StructDeclNode : public DeclNode {
std::string ident;
DeclSeqNode* fields;
StructType* sem_type;
StructDeclNode(const std::string& i, DeclSeqNode* f);
~StructDeclNode();
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
};
struct DataDeclNode : public DeclNode {
ExprNode* expr;
std::string str_label;
DataDeclNode(ExprNode* e);
~DataDeclNode();
void proto(DeclSeq* d, Environ* e);
void semant(Environ* e);
void translate(Codegen* g);
void transdata(Codegen* g);
};
struct VectorDeclNode : public DeclNode {
std::string ident, tag;
ExprSeqNode* exprs;
int kind;
VectorType* sem_type;
VectorDeclNode(const std::string& i, const std::string& t, ExprSeqNode* e, int k);
~VectorDeclNode();
void proto(DeclSeq* d, Environ* e);
void translate(Codegen* g);
};
@@ -1,8 +1,9 @@
#include "environ.hpp" #include "environ.hpp"
#include "std.hpp" #include "decl.hpp"
#include "label.hpp"
#include "type.hpp"
Environ::Environ(const string& f, Type* r, int l, Environ* gs) : funcLabel(f), returnType(r), level(l), globals(gs) Environ::Environ(const std::string& f, Type* r, int l, Environ* gs) : funcLabel(f), returnType(r), level(l), globals(gs)
{ {
decls = new DeclSeq(); decls = new DeclSeq();
typeDecls = new DeclSeq(); typeDecls = new DeclSeq();
@@ -29,7 +30,7 @@ Environ::~Environ()
delete types[k]; delete types[k];
} }
Decl* Environ::findDecl(const string& s) Decl* Environ::findDecl(const std::string& s)
{ {
for (Environ* e = this; e; e = e->globals) { for (Environ* e = this; e; e = e->globals) {
if (Decl* d = e->decls->findDecl(s)) { if (Decl* d = e->decls->findDecl(s)) {
@@ -43,7 +44,7 @@ Decl* Environ::findDecl(const string& s)
return 0; return 0;
} }
Decl* Environ::findFunc(const string& s) Decl* Environ::findFunc(const std::string& s)
{ {
for (Environ* e = this; e; e = e->globals) { for (Environ* e = this; e; e = e->globals) {
if (Decl* d = e->funcDecls->findDecl(s)) if (Decl* d = e->funcDecls->findDecl(s))
@@ -52,7 +53,7 @@ Decl* Environ::findFunc(const string& s)
return 0; return 0;
} }
Type* Environ::findType(const string& s) Type* Environ::findType(const std::string& s)
{ {
if (s == "%") if (s == "%")
return Type::int_type; return Type::int_type;
@@ -67,7 +68,7 @@ Type* Environ::findType(const string& s)
return 0; return 0;
} }
Label* Environ::findLabel(const string& s) Label* Environ::findLabel(const std::string& s)
{ {
for (int k = 0; k < labels.size(); ++k) for (int k = 0; k < labels.size(); ++k)
if (labels[k]->name == s) if (labels[k]->name == s)
@@ -75,16 +76,16 @@ Label* Environ::findLabel(const string& s)
return 0; return 0;
} }
Label* Environ::insertLabel(const string& s, int def, int src, int sz) Label* Environ::insertLabel(const std::string& s, int def, int src, int sz)
{ {
Label* l = new Label(s, def, src, sz); Label* l = new Label(s, def, src, sz);
labels.push_back(l); labels.push_back(l);
return l; return l;
} }
string Environ::setBreak(const string& s) std::string Environ::setBreak(const std::string& s)
{ {
string t = breakLabel; std::string t = breakLabel;
breakLabel = s; breakLabel = s;
return t; return t;
} }
+38
View File
@@ -0,0 +1,38 @@
/* An environ represent a stack frame block. */
#pragma once
#include <vector>
#include <string>
#include <list>
struct Decl;
struct DeclSeq;
struct Label;
struct Type;
class Environ {
public:
int level;
DeclSeq* decls;
DeclSeq* funcDecls;
DeclSeq* typeDecls;
std::vector<Type*> types;
std::vector<Label*> labels;
Environ* globals;
Type* returnType;
std::string funcLabel, breakLabel;
std::list<Environ*> children; //for delete!
Environ(const std::string& f, Type* r, int l, Environ* gs);
~Environ();
Decl* findDecl(const std::string& s);
Decl* findFunc(const std::string& s);
Type* findType(const std::string& s);
Label* findLabel(const std::string& s);
Label* insertLabel(const std::string& s, int def, int src, int sz);
std::string setBreak(const std::string& s);
};
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include <string>
struct BlitzException {
std::string ex; //what happened
int pos; //source offset
std::string file;
BlitzException(const std::string& ex) : ex(ex), pos(-1) {}
BlitzException(const std::string& ex, int pos, const std::string& t) : ex(ex), pos(pos), file(t) {}
};
@@ -1,9 +1,16 @@
#include "exprnode.hpp"
#include <cfloat>
#include <cmath>
#include "codegen.hpp"
#include "environ.hpp"
#include "toker.hpp"
#include "varnode.hpp"
#include "nodes.hpp" #include <stdutil.hpp>
#include "std.hpp"
#include <float.h> ExprNode::ExprNode() : sem_type(0) {}
#include <math.h>
ExprNode::ExprNode(Type* t) : sem_type(t) {}
////////////////////////////////// //////////////////////////////////
// Cast an expression to a type // // Cast an expression to a type //
@@ -19,6 +26,13 @@ ExprNode* ExprNode::castTo(Type* ty, Environ* e)
return cast; return cast;
} }
CastNode::CastNode(ExprNode* ex, Type* ty) : expr(ex), type(ty) {}
CastNode::~CastNode()
{
delete expr;
}
ExprNode* CastNode::semant(Environ* e) ExprNode* CastNode::semant(Environ* e)
{ {
if (!expr->sem_type) { if (!expr->sem_type) {
@@ -81,6 +95,18 @@ TNode* CastNode::translate(Codegen* g)
///////////////////////////// /////////////////////////////
// Sequence of Expressions // // Sequence of Expressions //
///////////////////////////// /////////////////////////////
ExprSeqNode::~ExprSeqNode() {}
void ExprSeqNode::push_back(std::shared_ptr<ExprNode> e)
{
exprs.push_back(e);
}
int ExprSeqNode::size()
{
return exprs.size();
}
void ExprSeqNode::semant(Environ* e) void ExprSeqNode::semant(Environ* e)
{ {
for (int k = 0; k < exprs.size(); ++k) { for (int k = 0; k < exprs.size(); ++k) {
@@ -158,6 +184,13 @@ void ExprSeqNode::castTo(Type* t, Environ* e)
} }
} }
CallNode::CallNode(const std::string& i, const std::string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {}
CallNode::~CallNode()
{
delete exprs;
}
/////////////////// ///////////////////
// Function call // // Function call //
/////////////////// ///////////////////
@@ -203,6 +236,13 @@ TNode* CallNode::translate(Codegen* g)
return t; return t;
} }
VarExprNode::VarExprNode(VarNode* v) : var(v) {}
VarExprNode::~VarExprNode()
{
delete var;
}
///////////////////////// /////////////////////////
// Variable expression // // Variable expression //
///////////////////////// /////////////////////////
@@ -246,7 +286,7 @@ float IntConstNode::floatValue()
return value; return value;
} }
string IntConstNode::stringValue() std::string IntConstNode::stringValue()
{ {
return itoa(value); return itoa(value);
} }
@@ -284,7 +324,7 @@ float FloatConstNode::floatValue()
return value; return value;
} }
string FloatConstNode::stringValue() std::string FloatConstNode::stringValue()
{ {
return ftoa(value); return ftoa(value);
} }
@@ -292,14 +332,14 @@ string FloatConstNode::stringValue()
///////////////////// /////////////////////
// String constant // // String constant //
///////////////////// /////////////////////
StringConstNode::StringConstNode(const string& s) : value(s) StringConstNode::StringConstNode(const std::string& s) : value(s)
{ {
sem_type = Type::string_type; sem_type = Type::string_type;
} }
TNode* StringConstNode::translate(Codegen* g) TNode* StringConstNode::translate(Codegen* g)
{ {
string lab = genLabel(); std::string lab = genLabel();
g->s_data(value, lab); g->s_data(value, lab);
return call("__bbStrConst", global(lab)); return call("__bbStrConst", global(lab));
} }
@@ -314,11 +354,18 @@ float StringConstNode::floatValue()
return (float)atof(value); return (float)atof(value);
} }
string StringConstNode::stringValue() std::string StringConstNode::stringValue()
{ {
return value; return value;
} }
UniExprNode::UniExprNode(int op, ExprNode* expr) : op(op), expr(expr) {}
UniExprNode::~UniExprNode()
{
delete expr;
}
//////////////////// ////////////////////
// Unary operator // // Unary operator //
//////////////////// ////////////////////
@@ -399,6 +446,14 @@ TNode* UniExprNode::translate(Codegen* g)
return new TNode(n, l, 0); return new TNode(n, l, 0);
} }
BinExprNode::BinExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {}
BinExprNode::~BinExprNode()
{
delete lhs;
delete rhs;
}
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
// boolean expression - accepts ints, returns ints // // boolean expression - accepts ints, returns ints //
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
@@ -466,6 +521,14 @@ TNode* BinExprNode::translate(Codegen* g)
return new TNode(n, l, r); return new TNode(n, l, r);
} }
ArithExprNode::ArithExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {}
ArithExprNode::~ArithExprNode()
{
delete lhs;
delete rhs;
}
/////////////////////////// ///////////////////////////
// arithmetic expression // // arithmetic expression //
/////////////////////////// ///////////////////////////
@@ -594,6 +657,14 @@ TNode* ArithExprNode::translate(Codegen* g)
return new TNode(n, l, r); return new TNode(n, l, r);
} }
RelExprNode::RelExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {}
RelExprNode::~RelExprNode()
{
delete lhs;
delete rhs;
}
///////////////////////// /////////////////////////
// relation expression // // relation expression //
///////////////////////// /////////////////////////
@@ -695,6 +766,8 @@ TNode* RelExprNode::translate(Codegen* g)
return compare(op, l, r, opType); return compare(op, l, r, opType);
} }
NewNode::NewNode(const std::string& i) : ident(i) {}
//////////////////// ////////////////////
// New expression // // New expression //
//////////////////// ////////////////////
@@ -713,6 +786,8 @@ TNode* NewNode::translate(Codegen* g)
return call("__bbObjNew", global("_t" + ident)); return call("__bbObjNew", global("_t" + ident));
} }
FirstNode::FirstNode(const std::string& i) : ident(i) {}
//////////////////// ////////////////////
// First of class // // First of class //
//////////////////// ////////////////////
@@ -729,6 +804,8 @@ TNode* FirstNode::translate(Codegen* g)
return call("__bbObjFirst", global("_t" + ident)); return call("__bbObjFirst", global("_t" + ident));
} }
LastNode::LastNode(const std::string& i) : ident(i) {}
/////////////////// ///////////////////
// Last of class // // Last of class //
/////////////////// ///////////////////
@@ -745,6 +822,13 @@ TNode* LastNode::translate(Codegen* g)
return call("__bbObjLast", global("_t" + ident)); return call("__bbObjLast", global("_t" + ident));
} }
AfterNode::AfterNode(ExprNode* e) : expr(e) {}
AfterNode::~AfterNode()
{
delete expr;
}
//////////////////// ////////////////////
// Next of object // // Next of object //
//////////////////// ////////////////////
@@ -767,6 +851,13 @@ TNode* AfterNode::translate(Codegen* g)
return call("__bbObjNext", t); return call("__bbObjNext", t);
} }
BeforeNode::BeforeNode(ExprNode* e) : expr(e) {}
BeforeNode::~BeforeNode()
{
delete expr;
}
//////////////////// ////////////////////
// Prev of object // // Prev of object //
//////////////////// ////////////////////
@@ -803,6 +894,13 @@ TNode* NullNode::translate(Codegen* g)
return new TNode(IR_CONST, 0, 0, 0); return new TNode(IR_CONST, 0, 0, 0);
} }
ObjectCastNode::ObjectCastNode(ExprNode* e, const std::string& t) : expr(e), type_ident(t) {}
ObjectCastNode::~ObjectCastNode()
{
delete expr;
}
///////////////// /////////////////
// Object cast // // Object cast //
///////////////// /////////////////
@@ -825,6 +923,13 @@ TNode* ObjectCastNode::translate(Codegen* g)
return t; return t;
} }
ObjectHandleNode::ObjectHandleNode(ExprNode* e) : expr(e) {}
ObjectHandleNode::~ObjectHandleNode()
{
delete expr;
}
/////////////////// ///////////////////
// Object Handle // // Object Handle //
/////////////////// ///////////////////
@@ -842,3 +947,13 @@ TNode* ObjectHandleNode::translate(Codegen* g)
TNode* t = expr->translate(g); TNode* t = expr->translate(g);
return call("__bbObjToHandle", t); return call("__bbObjToHandle", t);
} }
ExprNode* ConstNode::semant(Environ* e)
{
return this;
}
ConstNode* ConstNode::constNode()
{
return this;
}
@@ -1,15 +1,24 @@
#pragma once
#ifndef EXPRNODE_H #include <list>
#define EXPRNODE_H #include <string>
#include <vector>
#include "node.hpp" #include "node.hpp"
#include "type.hpp"
class Codegen;
class Environ;
struct DeclSeq;
struct Decl;
struct ConstNode; //is constant int,float or string struct ConstNode; //is constant int,float or string
struct VarNode;
struct ExprNode : public Node { class ExprNode : public Node {
Type* sem_type; std::shared_ptr<Type> sem_type;
ExprNode() : sem_type(0) {}
ExprNode(Type* t) : sem_type(t) {}
public:
ExprNode();
ExprNode(std::shared_ptr<Type> t);
ExprNode* castTo(Type* ty, Environ* e); ExprNode* castTo(Type* ty, Environ* e);
ExprNode* semant(Environ* e, Type* ty); ExprNode* semant(Environ* e, Type* ty);
@@ -22,114 +31,92 @@ struct ExprNode : public Node {
} }
}; };
struct ExprSeqNode : public Node { class ExprSeqNode : public Node {
vector<ExprNode*> exprs; std::list<std::shared_ptr<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);
};
#include "varnode.hpp" public:
~ExprSeqNode();
void push_back(std::shared_ptr<ExprNode> e);
int 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);
};
struct CastNode : public ExprNode { struct CastNode : public ExprNode {
ExprNode* expr; ExprNode* expr;
Type* type; Type* type;
CastNode(ExprNode* ex, Type* ty) : expr(ex), type(ty) {} CastNode(ExprNode* ex, Type* ty);
~CastNode() ~CastNode();
{
delete expr;
}
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
struct CallNode : public ExprNode { struct CallNode : public ExprNode {
string ident, tag; std::string ident, tag;
ExprSeqNode* exprs; ExprSeqNode* exprs;
Decl* sem_decl; Decl* sem_decl;
CallNode(const string& i, const string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {} CallNode(const std::string& i, const std::string& t, ExprSeqNode* e);
~CallNode() ~CallNode();
{
delete exprs;
}
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
struct VarExprNode : public ExprNode { struct VarExprNode : public ExprNode {
VarNode* var; VarNode* var;
VarExprNode(VarNode* v) : var(v) {} VarExprNode(VarNode* v);
~VarExprNode() ~VarExprNode();
{
delete var;
}
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
struct ConstNode : public ExprNode { struct ConstNode : public ExprNode {
ExprNode* semant(Environ* e) ExprNode* semant(Environ* e);
{ ConstNode* constNode();
return this; virtual int intValue() = 0;
} virtual float floatValue() = 0;
ConstNode* constNode() virtual std::string stringValue() = 0;
{
return this;
}
virtual int intValue() = 0;
virtual float floatValue() = 0;
virtual string stringValue() = 0;
}; };
struct IntConstNode : public ConstNode { struct IntConstNode : public ConstNode {
int value; int value;
IntConstNode(int n); IntConstNode(int n);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
int intValue(); int intValue();
float floatValue(); float floatValue();
string stringValue(); std::string stringValue();
}; };
struct FloatConstNode : public ConstNode { struct FloatConstNode : public ConstNode {
float value; float value;
FloatConstNode(float f); FloatConstNode(float f);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
int intValue(); int intValue();
float floatValue(); float floatValue();
string stringValue(); std::string stringValue();
}; };
struct StringConstNode : public ConstNode { struct StringConstNode : public ConstNode {
string value; std::string value;
StringConstNode(const string& s); StringConstNode(const std::string& s);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
int intValue(); int intValue();
float floatValue(); float floatValue();
string stringValue(); std::string stringValue();
}; };
struct UniExprNode : public ExprNode { struct UniExprNode : public ExprNode {
int op; int op;
ExprNode* expr; ExprNode* expr;
UniExprNode(int op, ExprNode* expr) : op(op), expr(expr) {} UniExprNode(int op, ExprNode* expr);
~UniExprNode() ~UniExprNode();
{
delete expr;
}
ExprNode* constize(); ExprNode* constize();
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
@@ -139,12 +126,8 @@ struct UniExprNode : public ExprNode {
struct BinExprNode : public ExprNode { struct BinExprNode : public ExprNode {
int op; int op;
ExprNode *lhs, *rhs; ExprNode *lhs, *rhs;
BinExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {} BinExprNode(int op, ExprNode* lhs, ExprNode* rhs);
~BinExprNode() ~BinExprNode();
{
delete lhs;
delete rhs;
}
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
@@ -153,12 +136,8 @@ struct BinExprNode : public ExprNode {
struct ArithExprNode : public ExprNode { struct ArithExprNode : public ExprNode {
int op; int op;
ExprNode *lhs, *rhs; ExprNode *lhs, *rhs;
ArithExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {} ArithExprNode(int op, ExprNode* lhs, ExprNode* rhs);
~ArithExprNode() ~ArithExprNode();
{
delete lhs;
delete rhs;
}
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
@@ -168,55 +147,45 @@ struct RelExprNode : public ExprNode {
int op; int op;
ExprNode *lhs, *rhs; ExprNode *lhs, *rhs;
Type* opType; Type* opType;
RelExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {} RelExprNode(int op, ExprNode* lhs, ExprNode* rhs);
~RelExprNode() ~RelExprNode();
{
delete lhs;
delete rhs;
}
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
struct NewNode : public ExprNode { struct NewNode : public ExprNode {
string ident; std::string ident;
NewNode(const string& i) : ident(i) {} NewNode(const std::string& i);
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
struct FirstNode : public ExprNode { struct FirstNode : public ExprNode {
string ident; std::string ident;
FirstNode(const string& i) : ident(i) {} FirstNode(const std::string& i);
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
struct LastNode : public ExprNode { struct LastNode : public ExprNode {
string ident; std::string ident;
LastNode(const string& i) : ident(i) {} LastNode(const std::string& i);
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
struct AfterNode : public ExprNode { struct AfterNode : public ExprNode {
ExprNode* expr; ExprNode* expr;
AfterNode(ExprNode* e) : expr(e) {} AfterNode(ExprNode* e);
~AfterNode() ~AfterNode();
{
delete expr;
}
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
struct BeforeNode : public ExprNode { struct BeforeNode : public ExprNode {
ExprNode* expr; ExprNode* expr;
BeforeNode(ExprNode* e) : expr(e) {} BeforeNode(ExprNode* e);
~BeforeNode() ~BeforeNode();
{
delete expr;
}
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
@@ -227,26 +196,18 @@ struct NullNode : public ExprNode {
}; };
struct ObjectCastNode : public ExprNode { struct ObjectCastNode : public ExprNode {
ExprNode* expr; ExprNode* expr;
string type_ident; std::string type_ident;
ObjectCastNode(ExprNode* e, const string& t) : expr(e), type_ident(t) {} ObjectCastNode(ExprNode* e, const std::string& t);
~ObjectCastNode() ~ObjectCastNode();
{
delete expr;
}
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
struct ObjectHandleNode : public ExprNode { struct ObjectHandleNode : public ExprNode {
ExprNode* expr; ExprNode* expr;
ObjectHandleNode(ExprNode* e) : expr(e) {} ObjectHandleNode(ExprNode* e);
~ObjectHandleNode() ~ObjectHandleNode();
{
delete expr;
}
ExprNode* semant(Environ* e); ExprNode* semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
#endif
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include <string>
struct Label {
std::string name; //name of label
int def, ref; //pos of defn and goto/restore src
int data_sz; //size of data at this label.
Label(const std::string& n, int d, int r, int sz) : name(n), def(d), ref(r), data_sz(sz) {}
};
+33 -24
View File
@@ -1,8 +1,17 @@
#include "node.hpp"
#include "codegen.hpp"
#include "decl.hpp"
#include "environ.hpp"
#include "ex.hpp"
#include "toker.hpp"
#include "type.hpp"
#include "nodes.hpp" #include "varnode.hpp"
#include "std.hpp" #include "exprnode.hpp"
set<string> Node::usedfuncs; #include <stdutil.hpp>
std::set<std::string> Node::usedfuncs;
/////////////////////////////// ///////////////////////////////
// generic exception thrower // // generic exception thrower //
@@ -12,19 +21,19 @@ void Node::ex()
ex("INTERNAL COMPILER ERROR"); ex("INTERNAL COMPILER ERROR");
} }
void Node::ex(const string& e) void Node::ex(const std::string& e)
{ {
throw Ex(e, -1, ""); throw BlitzException(e, -1, "");
} }
void Node::ex(const string& e, int pos) void Node::ex(const std::string& e, int pos)
{ {
throw Ex(e, pos, ""); throw BlitzException(e, pos, "");
} }
void Node::ex(const string& e, int pos, const string& f) void Node::ex(const std::string& e, int pos, const std::string& f)
{ {
throw Ex(e, pos, f); throw BlitzException(e, pos, f);
} }
/////////////////////////////// ///////////////////////////////
@@ -32,8 +41,8 @@ void Node::ex(const string& e, int pos, const string& f)
/////////////////////////////// ///////////////////////////////
VarNode* Node::genLocal(Environ* e, Type* ty) VarNode* Node::genLocal(Environ* e, Type* ty)
{ {
string t = genLabel(); std::string t = genLabel();
Decl* d = e->decls->insertDecl(t, ty, DECL_LOCAL); Decl* d = e->decls->insertDecl(t, ty, DECL_LOCAL);
return new DeclVarNode(d); return new DeclVarNode(d);
} }
@@ -119,9 +128,9 @@ TNode* Node::deleteVars(Environ* e)
{ {
TNode *t = 0, *l = 0, *p, *p1 = nullptr, *p2 = nullptr; TNode *t = 0, *l = 0, *p, *p1 = nullptr, *p2 = nullptr;
for (int k = 0; k < e->decls->size(); ++k) { for (int k = 0; k < e->decls->size(); ++k) {
Decl* d = e->decls->decls[k]; Decl* d = e->decls->decls[k];
Type* type = d->type; Type* type = d->type;
string func; std::string func;
if (type == Type::string_type) { if (type == Type::string_type) {
if (d->kind == DECL_LOCAL || d->kind == DECL_PARAM) { if (d->kind == DECL_LOCAL || d->kind == DECL_PARAM) {
func = "__bbStrRelease"; func = "__bbStrRelease";
@@ -212,7 +221,7 @@ TNode* Node::compare(int op, TNode* l, TNode* r, Type* ty)
///////////////////////////////// /////////////////////////////////
// calculate the type of a tag // // calculate the type of a tag //
///////////////////////////////// /////////////////////////////////
Type* Node::tagType(const string& tag, Environ* e) Type* Node::tagType(const std::string& tag, Environ* e)
{ {
Type* t; Type* t;
if (tag.size()) { if (tag.size()) {
@@ -227,7 +236,7 @@ Type* Node::tagType(const string& tag, Environ* e)
//////////////////////////////// ////////////////////////////////
// Generate a fresh ASM label // // Generate a fresh ASM label //
//////////////////////////////// ////////////////////////////////
string Node::genLabel() std::string Node::genLabel()
{ {
static int cnt; static int cnt;
return "_" + itoa(++cnt & 0x7fffffff); return "_" + itoa(++cnt & 0x7fffffff);
@@ -236,7 +245,7 @@ string Node::genLabel()
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
// create a stmt-type function call with int result // // create a stmt-type function call with int result //
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
TNode* Node::call(const string& func, TNode* a0, TNode* a1, TNode* a2) TNode* Node::call(const std::string& func, TNode* a0, TNode* a1, TNode* a2)
{ {
int size = 0; int size = 0;
TNode* t = 0; TNode* t = 0;
@@ -259,7 +268,7 @@ TNode* Node::call(const string& func, TNode* a0, TNode* a1, TNode* a2)
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
// create a stmt-type function call with float result // // create a stmt-type function call with float result //
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
TNode* Node::fcall(const string& func, TNode* a0, TNode* a1, TNode* a2) TNode* Node::fcall(const std::string& func, TNode* a0, TNode* a1, TNode* a2)
{ {
int size = 0; int size = 0;
TNode* t = 0; TNode* t = 0;
@@ -289,7 +298,7 @@ TNode* Node::move(TNode* src, TNode* dest)
return new TNode(IR_MOVE, src, dest); return new TNode(IR_MOVE, src, dest);
} }
TNode* Node::global(const string& s) TNode* Node::global(const std::string& s)
{ {
return new TNode(IR_GLOBAL, 0, 0, s); return new TNode(IR_GLOBAL, 0, 0, s);
} }
@@ -329,27 +338,27 @@ TNode* Node::ret()
return new TNode(IR_RET, 0, 0); return new TNode(IR_RET, 0, 0);
} }
TNode* Node::jsr(const string& s) TNode* Node::jsr(const std::string& s)
{ {
return new TNode(IR_JSR, 0, 0, s); return new TNode(IR_JSR, 0, 0, s);
} }
TNode* Node::jump(const string& s) TNode* Node::jump(const std::string& s)
{ {
return new TNode(IR_JUMP, 0, 0, s); return new TNode(IR_JUMP, 0, 0, s);
} }
TNode* Node::jumpt(TNode* expr, const string& s) TNode* Node::jumpt(TNode* expr, const std::string& s)
{ {
return new TNode(IR_JUMPT, expr, 0, s); return new TNode(IR_JUMPT, expr, 0, s);
} }
TNode* Node::jumpf(TNode* expr, const string& s) TNode* Node::jumpf(TNode* expr, const std::string& s)
{ {
return new TNode(IR_JUMPF, expr, 0, s); return new TNode(IR_JUMPF, expr, 0, s);
} }
TNode* Node::jumpge(TNode* l, TNode* r, const string& s) TNode* Node::jumpge(TNode* l, TNode* r, const std::string& s)
{ {
return new TNode(IR_JUMPGE, l, r, s); return new TNode(IR_JUMPGE, l, r, s);
} }
+54
View File
@@ -0,0 +1,54 @@
#pragma once
#include <set>
#include <string>
#include "type.hpp"
struct VarNode;
struct ConstNode;
class Environ;
struct TNode;
class Node {
public:
virtual ~Node() {}
public:
//used user funcs...
static std::set<std::string> usedfuncs;
//helper funcs
static void ex();
static void ex(const std::string& e);
static void ex(const std::string& e, int pos);
static void ex(const std::string& e, int pos, const std::string& f);
static std::string genLabel();
static VarNode* genLocal(Environ* e, Type* ty);
static TNode* compare(int op, TNode* l, TNode* r, Type* ty);
static ConstNode* constValue(Type* ty);
static int enumVars(Environ* e);
static Type* tagType(const std::string& s, Environ* e);
static TNode* createVars(Environ* e);
static TNode* deleteVars(Environ* e);
static TNode* seq(TNode* l, TNode* r);
static TNode* move(TNode* src, TNode* dest);
static TNode* global(const std::string& s);
static TNode* local(int offset);
static TNode* arg(int offset);
static TNode* mem(TNode* ref);
static TNode* add(TNode* l, TNode* r);
static TNode* mul(TNode* l, TNode* r);
static TNode* iconst(int n);
static TNode* ret();
static TNode* jsr(const std::string& s);
static TNode* jump(const std::string& s);
static TNode* jumpt(TNode* cond, const std::string& s);
static TNode* jumpf(TNode* cond, const std::string& s);
static TNode* jumpge(TNode* l, TNode* r, const std::string& s);
static TNode* call(const std::string& func, TNode* a0 = 0, TNode* a1 = 0, TNode* a2 = 0);
static TNode* fcall(const std::string& func, TNode* a0 = 0, TNode* a1 = 0, TNode* a2 = 0);
};
@@ -1,10 +1,5 @@
#pragma once
#ifndef NODES_H
#define NODES_H
#include "declnode.hpp" #include "declnode.hpp"
#include "exprnode.hpp" #include "exprnode.hpp"
#include "prognode.hpp" #include "prognode.hpp"
#include "stmtnode.hpp" #include "stmtnode.hpp"
#endif
+156 -146
View File
@@ -1,13 +1,14 @@
#include "parser.hpp" #include "parser.hpp"
#include <cstdlib> #include <cstdlib>
#include "std.hpp" #include <fstream>
#include "ex.hpp"
#include "varnode.hpp"
#include <Windows.h>
#include <stdutil.hpp>
#ifdef DEMO
static const int TEXTLIMIT = 16384;
#else
static const int TEXTLIMIT = 1024 * 1024 - 1; static const int TEXTLIMIT = 1024 * 1024 - 1;
#endif
enum { STMTS_PROG, STMTS_BLOCK, STMTS_LINE }; enum { STMTS_PROG, STMTS_BLOCK, STMTS_LINE };
@@ -18,38 +19,31 @@ static bool isTerm(int c)
Parser::Parser(Toker& t) : toker(&t), main_toker(&t) {} Parser::Parser(Toker& t) : toker(&t), main_toker(&t) {}
ProgNode* Parser::parse(const string& main) std::shared_ptr<ProgNode> Parser::parse(const std::string& main)
{ {
incfile = main; incfile = main;
consts = new DeclSeqNode(); consts = std::make_shared<DeclSeqNode>();
structs = new DeclSeqNode(); structs = std::make_shared<DeclSeqNode>();
funcs = new DeclSeqNode(); funcs = std::make_shared<DeclSeqNode>();
datas = new DeclSeqNode(); datas = std::make_shared<DeclSeqNode>();
StmtSeqNode* stmts = 0;
try { std::shared_ptr<StmtSeqNode> stmts;
stmts = parseStmtSeq(STMTS_PROG);
if (toker->curr() != EOF) stmts = parseStmtSeq(STMTS_PROG);
exp("end-of-file"); if (toker->curr() != EOF) {
} catch (Ex) { exp("end-of-file");
delete stmts;
delete datas;
delete funcs;
delete structs;
delete consts;
throw;
} }
return new ProgNode(consts, structs, funcs, datas, stmts); return std::make_shared<ProgNode>(consts, structs, funcs, datas, stmts);
} }
void Parser::ex(const string& s) void Parser::ex(const std::string& s)
{ {
throw Ex(s, toker->pos(), incfile); throw BlitzException(s, toker->pos(), incfile);
} }
void Parser::exp(const string& s) void Parser::exp(const std::string& s)
{ {
switch (toker->curr()) { switch (toker->curr()) {
case NEXT: case NEXT:
@@ -75,11 +69,11 @@ void Parser::exp(const string& s)
ex("Expecting " + s); ex("Expecting " + s);
} }
string Parser::parseIdent() std::string Parser::parseIdent()
{ {
if (toker->curr() != IDENT) if (toker->curr() != IDENT)
exp("identifier"); exp("identifier");
string t = toker->text(); std::string t = toker->text();
toker->next(); toker->next();
return t; return t;
} }
@@ -87,36 +81,32 @@ string Parser::parseIdent()
void Parser::parseChar(int c) void Parser::parseChar(int c)
{ {
if (toker->curr() != c) if (toker->curr() != c)
exp(string("'") + char(c) + string("'")); exp(std::string("'") + char(c) + std::string("'"));
toker->next(); toker->next();
} }
StmtSeqNode* Parser::parseStmtSeq(int scope) std::shared_ptr<StmtSeqNode> Parser::parseStmtSeq(int scope)
{ {
a_ptr<StmtSeqNode> stmts(new StmtSeqNode(incfile)); std::shared_ptr<StmtSeqNode> stmts = std::make_shared<StmtSeqNode>(incfile);
parseStmtSeq(stmts, scope); parseStmtSeq(stmts, scope);
return stmts.release(); return stmts;
} }
void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope) void Parser::parseStmtSeq(std::shared_ptr<StmtSeqNode> stmts, int scope)
{ {
for (;;) { for (;;) {
while (toker->curr() == ':' || (scope != STMTS_LINE && toker->curr() == '\n')) while (toker->curr() == ':' || (scope != STMTS_LINE && toker->curr() == '\n')) {
toker->next(); toker->next();
}
StmtNode* result = 0; StmtNode* result = 0;
int pos = toker->pos(); int pos = toker->pos();
#ifdef DEMO
if (Toker::chars_toked > TEXTLIMIT) {
ex("Demo version source limit exceeded");
}
#endif
switch (toker->curr()) { switch (toker->curr()) {
case INCLUDE: { case INCLUDE: {
if (toker->next() != STRINGCONST) if (toker->next() != STRINGCONST)
exp("include filename"); exp("include filename");
string inc = toker->text(); std::string inc = toker->text();
toker->next(); toker->next();
inc = inc.substr(1, inc.size() - 2); inc = inc.substr(1, inc.size() - 2);
@@ -129,32 +119,31 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
if (included.find(inc) != included.end()) if (included.find(inc) != included.end())
break; break;
ifstream i_stream(inc.c_str()); std::ifstream i_stream(inc.c_str());
if (!i_stream.good()) if (!i_stream.good())
ex("Unable to open include file"); ex("Unable to open include file");
Toker i_toker(i_stream); std::swap(this->incfile, inc);
string t_inc = incfile; std::shared_ptr<Toker> i_toker = std::make_shared<Toker>(i_stream);
incfile = inc; std::swap(this->toker, i_toker);
Toker* t_toker = toker;
toker = &i_toker;
included.insert(incfile); included.insert(incfile);
a_ptr<StmtSeqNode> ss(parseStmtSeq(scope)); std::shared_ptr<StmtSeqNode> ss = parseStmtSeq(scope);
if (toker->curr() != EOF) if (toker->curr() != EOF) {
exp("end-of-file"); exp("end-of-file");
}
result = new IncludeNode(incfile, ss.release()); result = new IncludeNode(incfile, ss);
toker = t_toker; std::swap(this->toker, i_toker);
incfile = t_inc; std::swap(this->incfile, inc);
} break; } break;
case IDENT: { case IDENT: {
string ident = toker->text(); std::string ident = toker->text();
toker->next(); toker->next();
string tag = parseTypeTag(); std::string tag = parseTypeTag();
if (arrayDecls.find(ident) == arrayDecls.end() && toker->curr() != '=' && toker->curr() != '\\' if (arrayDecls.find(ident) == arrayDecls.end() && toker->curr() != '=' && toker->curr() != '\\'
&& toker->curr() != '[') { && toker->curr() != '[') {
//must be a function //must be a function
@@ -201,13 +190,13 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
} break; } break;
case WHILE: { case WHILE: {
toker->next(); toker->next();
a_ptr<ExprNode> expr(parseExpr(false)); std::shared_ptr<ExprNode> expr = parseExpr(false);
a_ptr<StmtSeqNode> stmts(parseStmtSeq(STMTS_BLOCK)); std::shared_ptr<StmtSeqNode> stmts = parseStmtSeq(STMTS_BLOCK);
int pos = toker->pos(); int pos = toker->pos();
if (toker->curr() != WEND) if (toker->curr() != WEND)
exp("'Wend'"); exp("'Wend'");
toker->next(); toker->next();
result = new WhileNode(expr.release(), stmts.release(), pos); result = new WhileNode(expr, stmts, pos);
} break; } break;
case REPEAT: { case REPEAT: {
toker->next(); toker->next();
@@ -261,9 +250,9 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
exp("variable assignment"); exp("variable assignment");
if (toker->next() == EACH) { if (toker->next() == EACH) {
toker->next(); toker->next();
string ident = parseIdent(); std::string ident = parseIdent();
stmts = parseStmtSeq(STMTS_BLOCK); stmts = parseStmtSeq(STMTS_BLOCK);
int pos = toker->pos(); int pos = toker->pos();
if (toker->curr() != NEXT) if (toker->curr() != NEXT)
exp("'Next'"); exp("'Next'");
toker->next(); toker->next();
@@ -295,13 +284,13 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
} break; } break;
case GOTO: { case GOTO: {
toker->next(); toker->next();
string t = parseIdent(); std::string t = parseIdent();
result = new GotoNode(t); result = new GotoNode(t);
} break; } break;
case GOSUB: { case GOSUB: {
toker->next(); toker->next();
string t = parseIdent(); std::string t = parseIdent();
result = new GosubNode(t); result = new GosubNode(t);
} break; } break;
case RETURN: { case RETURN: {
toker->next(); toker->next();
@@ -310,8 +299,8 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
case BBDELETE: { case BBDELETE: {
if (toker->next() == EACH) { if (toker->next() == EACH) {
toker->next(); toker->next();
string t = parseIdent(); std::string t = parseIdent();
result = new DeleteEachNode(t); result = new DeleteEachNode(t);
} else { } else {
ExprNode* expr = parseExpr(false); ExprNode* expr = parseExpr(false);
result = new DeleteNode(expr); result = new DeleteNode(expr);
@@ -406,8 +395,8 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
break; break;
case '.': { case '.': {
toker->next(); toker->next();
string t = parseIdent(); std::string t = parseIdent();
result = new LabelNode(t, datas->size()); result = new LabelNode(t, datas->size());
} break; } break;
default: default:
return; return;
@@ -420,7 +409,7 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
} }
} }
string Parser::parseTypeTag() std::string Parser::parseTypeTag()
{ {
switch (toker->curr()) { switch (toker->curr()) {
case '%': case '%':
@@ -439,14 +428,14 @@ string Parser::parseTypeTag()
return ""; return "";
} }
VarNode* Parser::parseVar() std::shared_ptr<VarNode> Parser::parseVar()
{ {
string ident = parseIdent(); std::string ident = parseIdent();
string tag = parseTypeTag(); std::string tag = parseTypeTag();
return parseVar(ident, tag); return parseVar(ident, tag);
} }
VarNode* Parser::parseVar(const string& ident, const string& tag) std::shared_ptr<VarNode> Parser::parseVar(const std::string& ident, const std::string& tag)
{ {
a_ptr<VarNode> var; a_ptr<VarNode> var;
if (toker->curr() == '(') { if (toker->curr() == '(') {
@@ -462,10 +451,10 @@ VarNode* Parser::parseVar(const string& ident, const string& tag)
for (;;) { for (;;) {
if (toker->curr() == '\\') { if (toker->curr() == '\\') {
toker->next(); toker->next();
string ident = parseIdent(); std::string ident = parseIdent();
string tag = parseTypeTag(); std::string tag = parseTypeTag();
ExprNode* expr = new VarExprNode(var.release()); ExprNode* expr = new VarExprNode(var.release());
var = new FieldVarNode(expr, ident, tag); var = new FieldVarNode(expr, ident, tag);
} else if (toker->curr() == '[') { } else if (toker->curr() == '[') {
toker->next(); toker->next();
a_ptr<ExprSeqNode> exprs(parseExprSeq()); a_ptr<ExprSeqNode> exprs(parseExprSeq());
@@ -481,12 +470,12 @@ VarNode* Parser::parseVar(const string& ident, const string& tag)
return var.release(); return var.release();
} }
DeclNode* Parser::parseVarDecl(int kind, bool constant) std::shared_ptr<DeclNode> Parser::parseVarDecl(int kind, bool constant)
{ {
int pos = toker->pos(); int pos = toker->pos();
string ident = parseIdent(); std::string ident = parseIdent();
string tag = parseTypeTag(); std::string tag = parseTypeTag();
DeclNode* d; DeclNode* d;
if (toker->curr() == '[') { if (toker->curr() == '[') {
if (constant) if (constant)
ex("Blitz arrays may not be constant"); ex("Blitz arrays may not be constant");
@@ -510,11 +499,11 @@ DeclNode* Parser::parseVarDecl(int kind, bool constant)
return d; return d;
} }
DimNode* Parser::parseArrayDecl() std::shared_ptr<DimNode> Parser::parseArrayDecl()
{ {
int pos = toker->pos(); int pos = toker->pos();
string ident = parseIdent(); std::string ident = parseIdent();
string tag = parseTypeTag(); std::string tag = parseTypeTag();
if (toker->curr() != '(') if (toker->curr() != '(')
exp("'('"); exp("'('");
toker->next(); toker->next();
@@ -530,11 +519,11 @@ DimNode* Parser::parseArrayDecl()
return d; return d;
} }
DeclNode* Parser::parseFuncDecl() std::shared_ptr<DeclNode> Parser::parseFuncDecl()
{ {
int pos = toker->pos(); int pos = toker->pos();
string ident = parseIdent(); std::string ident = parseIdent();
string tag = parseTypeTag(); std::string tag = parseTypeTag();
if (toker->curr() != '(') if (toker->curr() != '(')
exp("'('"); exp("'('");
a_ptr<DeclSeqNode> params(new DeclSeqNode()); a_ptr<DeclSeqNode> params(new DeclSeqNode());
@@ -562,10 +551,10 @@ DeclNode* Parser::parseFuncDecl()
return d; return d;
} }
DeclNode* Parser::parseStructDecl() std::shared_ptr<DeclNode> Parser::parseStructDecl()
{ {
int pos = toker->pos(); int pos = toker->pos();
string ident = parseIdent(); std::string ident = parseIdent();
while (toker->curr() == '\n') while (toker->curr() == '\n')
toker->next(); toker->next();
a_ptr<DeclSeqNode> fields(new DeclSeqNode()); a_ptr<DeclSeqNode> fields(new DeclSeqNode());
@@ -586,7 +575,7 @@ DeclNode* Parser::parseStructDecl()
return d; return d;
} }
IfNode* Parser::parseIf() std::shared_ptr<IfNode> Parser::parseIf()
{ {
a_ptr<ExprNode> expr; a_ptr<ExprNode> expr;
a_ptr<StmtSeqNode> stmts, elseOpt; a_ptr<StmtSeqNode> stmts, elseOpt;
@@ -618,124 +607,145 @@ IfNode* Parser::parseIf()
return new IfNode(expr.release(), stmts.release(), elseOpt.release()); return new IfNode(expr.release(), stmts.release(), elseOpt.release());
} }
ExprSeqNode* Parser::parseExprSeq() std::shared_ptr<ExprSeqNode> Parser::parseExprSeq()
{ {
a_ptr<ExprSeqNode> exprs(new ExprSeqNode()); std::shared_ptr<ExprSeqNode> exprs = std::make_shared<ExprSeqNode>();
bool opt = true; bool opt = true;
while (ExprNode* e = parseExpr(opt)) { while (std::shared_ptr<ExprNode> e = parseExpr(opt)) {
exprs->push_back(e); exprs->push_back(e);
if (toker->curr() != ',') if (toker->curr() != ',')
break; break;
toker->next(); toker->next();
opt = false; opt = false;
} }
return exprs.release(); return exprs;
} }
ExprNode* Parser::parseExpr(bool opt) std::shared_ptr<ExprNode> Parser::parseExpr(bool opt)
{ {
if (toker->curr() == NOT) { if (toker->curr() == NOT) {
toker->next(); toker->next();
ExprNode* expr = parseExpr1(false); std::shared_ptr<ExprNode> expr = parseExpr1(false);
return new RelExprNode('=', expr, new IntConstNode(0)); return std::make_shared<RelExprNode>('=', expr, std::make_shared<IntConstNode>(0));
} }
return parseExpr1(opt); return parseExpr1(opt);
} }
ExprNode* Parser::parseExpr1(bool opt) std::shared_ptr<ExprNode> Parser::parseExpr1(bool opt)
{ {
a_ptr<ExprNode> lhs(parseExpr2(opt)); std::shared_ptr<ExprNode> rhs;
std::shared_ptr<ExprNode> lhs = parseExpr2(opt);
if (!lhs) if (!lhs)
return 0; return 0;
for (;;) { for (;;) {
int c = toker->curr(); int c = toker->curr();
if (c != AND && c != OR && c != XOR) if (c != AND && c != OR && c != XOR) {
return lhs.release(); return lhs;
}
toker->next(); toker->next();
ExprNode* rhs = parseExpr2(false);
lhs = new BinExprNode(c, lhs.release(), rhs); rhs = parseExpr2(false);
lhs = std::make_shared<BinExprNode>(c, lhs, rhs);
} }
} }
ExprNode* Parser::parseExpr2(bool opt) std::shared_ptr<ExprNode> Parser::parseExpr2(bool opt)
{ {
a_ptr<ExprNode> lhs(parseExpr3(opt)); std::shared_ptr<ExprNode> rhs;
std::shared_ptr<ExprNode> lhs = parseExpr3(opt);
if (!lhs) if (!lhs)
return 0; return 0;
for (;;) { for (;;) {
int c = toker->curr(); int c = toker->curr();
if (c != '<' && c != '>' && c != '=' && c != LE && c != GE && c != NE) if (c != '<' && c != '>' && c != '=' && c != LE && c != GE && c != NE) {
return lhs.release(); return lhs;
}
toker->next(); toker->next();
ExprNode* rhs = parseExpr3(false);
lhs = new RelExprNode(c, lhs.release(), rhs); rhs = parseExpr3(false);
lhs = std::make_shared<RelExprNode>(c, lhs, rhs);
} }
} }
ExprNode* Parser::parseExpr3(bool opt) std::shared_ptr<ExprNode> Parser::parseExpr3(bool opt)
{ {
a_ptr<ExprNode> lhs(parseExpr4(opt)); std::shared_ptr<ExprNode> rhs;
std::shared_ptr<ExprNode> lhs = parseExpr4(opt);
if (!lhs) if (!lhs)
return 0; return 0;
for (;;) { for (;;) {
int c = toker->curr(); int c = toker->curr();
if (c != '+' && c != '-') if (c != '+' && c != '-') {
return lhs.release(); return lhs;
}
toker->next(); toker->next();
ExprNode* rhs = parseExpr4(false);
lhs = new ArithExprNode(c, lhs.release(), rhs); rhs = parseExpr4(false);
lhs = std::make_shared<ArithExprNode>(c, lhs, rhs);
} }
} }
ExprNode* Parser::parseExpr4(bool opt) std::shared_ptr<ExprNode> Parser::parseExpr4(bool opt)
{ {
a_ptr<ExprNode> lhs(parseExpr5(opt)); std::shared_ptr<ExprNode> rhs;
std::shared_ptr<ExprNode> lhs = parseExpr5(opt);
if (!lhs) if (!lhs)
return 0; return 0;
for (;;) { for (;;) {
int c = toker->curr(); int c = toker->curr();
if (c != SHL && c != SHR && c != SAR) if (c != SHL && c != SHR && c != SAR) {
return lhs.release(); return lhs;
}
toker->next(); toker->next();
ExprNode* rhs = parseExpr5(false);
lhs = new BinExprNode(c, lhs.release(), rhs); rhs = parseExpr5(false);
lhs = std::make_shared<BinExprNode>(c, lhs, rhs);
} }
} }
ExprNode* Parser::parseExpr5(bool opt) std::shared_ptr<ExprNode> Parser::parseExpr5(bool opt)
{ {
a_ptr<ExprNode> lhs(parseExpr6(opt)); std::shared_ptr<ExprNode> rhs;
if (!lhs) std::shared_ptr<ExprNode> lhs = parseExpr6(opt);
if (!lhs) {
return 0; return 0;
}
for (;;) { for (;;) {
int c = toker->curr(); int c = toker->curr();
if (c != '*' && c != '/' && c != MOD) if (c != '*' && c != '/' && c != MOD) {
return lhs.release(); return lhs;
}
toker->next(); toker->next();
ExprNode* rhs = parseExpr6(false);
lhs = new ArithExprNode(c, lhs.release(), rhs); rhs = parseExpr6(false);
lhs = std::make_shared<ArithExprNode>(c, lhs, rhs);
} }
} }
ExprNode* Parser::parseExpr6(bool opt) std::shared_ptr<ExprNode> Parser::parseExpr6(bool opt)
{ {
a_ptr<ExprNode> lhs(parseUniExpr(opt)); std::shared_ptr<ExprNode> rhs;
if (!lhs) std::shared_ptr<ExprNode> lhs = parseUniExpr(opt);
return 0; if (!lhs) {
return nullptr;
}
for (;;) { for (;;) {
int c = toker->curr(); int c = toker->curr();
if (c != '^') if (c != '^') {
return lhs.release(); return lhs;
}
toker->next(); toker->next();
ExprNode* rhs = parseUniExpr(false);
lhs = new ArithExprNode(c, lhs.release(), rhs); rhs = parseUniExpr(false);
lhs = std::make_shared<ArithExprNode>(c, lhs, rhs);
} }
} }
ExprNode* Parser::parseUniExpr(bool opt) std::shared_ptr<ExprNode> Parser::parseUniExpr(bool opt)
{ {
ExprNode* result = 0; std::shared_ptr<ExprNode> result;
string t; std::string t;
int c = toker->curr(); int c = toker->curr();
switch (c) { switch (c) {
@@ -798,10 +808,10 @@ ExprNode* Parser::parseUniExpr(bool opt)
return result; return result;
} }
ExprNode* Parser::parsePrimary(bool opt) std::shared_ptr<ExprNode> Parser::parsePrimary(bool opt)
{ {
a_ptr<ExprNode> expr; a_ptr<ExprNode> expr;
string t, ident, tag; std::string t, ident, tag;
ExprNode* result = 0; ExprNode* result = 0;
int n, k; int n, k;
+63
View File
@@ -0,0 +1,63 @@
/*
The parser builds an abstact syntax tree from input tokens.
*/
#pragma once
#include <map>
#include <memory>
#include <set>
#include <string>
#include "nodes.hpp"
#include "toker.hpp"
class Parser {
std::string incfile;
std::set<std::string> included;
std::map<std::string, DimNode*> arrayDecls;
std::shared_ptr<Toker> toker;
std::shared_ptr<Toker> main_toker;
std::shared_ptr<DeclSeqNode> consts;
std::shared_ptr<DeclSeqNode> structs;
std::shared_ptr<DeclSeqNode> funcs;
std::shared_ptr<DeclSeqNode> datas;
std::shared_ptr<StmtSeqNode> parseStmtSeq(int scope);
void parseStmtSeq(std::shared_ptr<StmtSeqNode> stmts, int scope);
void ex(const std::string& s);
void exp(const std::string& s);
std::string parseIdent();
void parseChar(int c);
std::string parseTypeTag();
std::shared_ptr<VarNode> parseVar();
std::shared_ptr<VarNode> parseVar(const std::string& ident, const std::string& tag);
std::shared_ptr<CallNode> parseCall(const std::string& ident, const std::string& tag);
std::shared_ptr<IfNode> parseIf();
std::shared_ptr<DeclNode> parseVarDecl(int kind, bool constant);
std::shared_ptr<DimNode> parseArrayDecl();
std::shared_ptr<DeclNode> parseFuncDecl();
std::shared_ptr<DeclNode> parseStructDecl();
std::shared_ptr<ExprSeqNode> parseExprSeq();
std::shared_ptr<ExprNode> parseExpr(bool opt);
std::shared_ptr<ExprNode> parseExpr1(bool opt); //And, Or, Eor
std::shared_ptr<ExprNode> parseExpr2(bool opt); //<,=,>,<=,<>,>=
std::shared_ptr<ExprNode> parseExpr3(bool opt); //+,-
std::shared_ptr<ExprNode> parseExpr4(bool opt); //Lsr,Lsr,Asr
std::shared_ptr<ExprNode> parseExpr5(bool opt); //*,/,Mod
std::shared_ptr<ExprNode> parseExpr6(bool opt); //^
std::shared_ptr<ExprNode> parseUniExpr(bool opt); //+,-,Not,~
std::shared_ptr<ExprNode> parsePrimary(bool opt);
public:
Parser(Toker& t);
~Parser();
std::shared_ptr<ProgNode> parse(std::string const& main);
};
@@ -1,17 +1,38 @@
#include "prognode.hpp"
#include <map>
#include "codegen.hpp"
#include "declnode.hpp"
#include "environ.hpp"
#include "label.hpp"
#include "stmtnode.hpp"
#include "nodes.hpp" #include <stdutil.hpp>
#include "std.hpp"
ProgNode::ProgNode(std::shared_ptr<DeclSeqNode> constants, std::shared_ptr<DeclSeqNode> structures,
std::shared_ptr<DeclSeqNode> functions, std::shared_ptr<DeclSeqNode> datas,
std::shared_ptr<StmtSeqNode> statements)
: consts(constants), structs(structures), funcs(functions), datas(datas), stmts(statements)
{}
ProgNode::~ProgNode()
{
this->consts.reset();
this->structs.reset();
this->funcs.reset();
this->datas.reset();
this->stmts.reset();
}
////////////////// //////////////////
// The program! // // The program! //
////////////////// //////////////////
Environ* ProgNode::semant(Environ* e) std::shared_ptr<Environ> ProgNode::semant(Environ* e)
{ {
file_lab = genLabel(); file_lab = genLabel();
StmtSeqNode::reset(stmts->file, file_lab); StmtSeqNode::reset(stmts->file, file_lab);
a_ptr<Environ> env(new Environ(genLabel(), Type::int_type, 0, e)); std::shared_ptr<Environ> env = std::make_shared<Environ>(genLabel(), Type::int_type, 0, 0);
consts->proto(env->decls, env); consts->proto(env->decls, env);
structs->proto(env->typeDecls, env); structs->proto(env->typeDecls, env);
@@ -22,11 +43,11 @@ Environ* ProgNode::semant(Environ* e)
datas->proto(env->decls, env); datas->proto(env->decls, env);
datas->semant(env); datas->semant(env);
sem_env = env.release(); sem_env = env;
return sem_env; return env;
} }
void ProgNode::translate(Codegen* g, const vector<UserFunc>& usrfuncs) void ProgNode::translate(Codegen* g, const std::vector<UserFunc>& usrfuncs)
{ {
int k; int k;
@@ -55,7 +76,7 @@ void ProgNode::translate(Codegen* g, const vector<UserFunc>& usrfuncs)
if (t) if (t)
g->code(t); g->code(t);
if (g->debug) { if (g->debug) {
string t = genLabel(); std::string t = genLabel();
g->s_data("<main program>", t); g->s_data("<main program>", t);
g->code(call("__bbDebugEnter", local(0), iconst((int)sem_env), global(t))); g->code(call("__bbDebugEnter", local(0), iconst((int)sem_env), global(t)));
} }
@@ -92,7 +113,7 @@ void ProgNode::translate(Codegen* g, const vector<UserFunc>& usrfuncs)
datas->translate(g); datas->translate(g);
//library functions //library functions
map<string, vector<int>> libFuncs; std::map<std::string, std::vector<int>> libFuncs;
//lib ptrs //lib ptrs
g->flush(); g->flush();
@@ -111,12 +132,12 @@ void ProgNode::translate(Codegen* g, const vector<UserFunc>& usrfuncs)
//LIBS chunk //LIBS chunk
g->flush(); g->flush();
g->label("__LIBS"); g->label("__LIBS");
map<string, vector<int>>::const_iterator lf_it; std::map<std::string, std::vector<int>>::const_iterator lf_it;
for (lf_it = libFuncs.begin(); lf_it != libFuncs.end(); ++lf_it) { for (lf_it = libFuncs.begin(); lf_it != libFuncs.end(); ++lf_it) {
//lib name //lib name
g->s_data(lf_it->first); g->s_data(lf_it->first);
const vector<int>& fns = lf_it->second; const std::vector<int>& fns = lf_it->second;
for (int j = 0; j < fns.size(); ++j) { for (int j = 0; j < fns.size(); ++j) {
const UserFunc& fn = usrfuncs[fns[j]]; const UserFunc& fn = usrfuncs[fns[j]];
@@ -140,3 +161,8 @@ void ProgNode::translate(Codegen* g, const vector<UserFunc>& usrfuncs)
//Thats IT! //Thats IT!
g->flush(); g->flush();
} }
UserFunc::UserFunc(const UserFunc& t) : ident(t.ident), proc(t.proc), lib(t.lib) {}
UserFunc::UserFunc(const std::string& id, const std::string& pr, const std::string& lb) : ident(id), proc(pr), lib(lb)
{}
+35
View File
@@ -0,0 +1,35 @@
#pragma once
#include <string>
#include <vector>
#include "node.hpp"
class Codegen;
class Environ;
struct DeclSeqNode;
struct StmtSeqNode;
struct UserFunc {
std::string ident, proc, lib;
UserFunc(const UserFunc& t);
UserFunc(const std::string& id, const std::string& pr, const std::string& lb);
};
class ProgNode : public Node {
std::shared_ptr<DeclSeqNode> consts;
std::shared_ptr<DeclSeqNode> structs;
std::shared_ptr<DeclSeqNode> funcs;
std::shared_ptr<DeclSeqNode> datas;
std::shared_ptr<StmtSeqNode> stmts;
std::shared_ptr<Environ> sem_env;
std::string file_lab;
public:
ProgNode(std::shared_ptr<DeclSeqNode> constants, std::shared_ptr<DeclSeqNode> structures, std::shared_ptr<DeclSeqNode> functions,
std::shared_ptr<DeclSeqNode> datas, std::shared_ptr<StmtSeqNode> statements);
~ProgNode();
std::shared_ptr<Environ> semant(Environ* e);
void translate(Codegen* g, const std::vector<UserFunc>& userfuncs);
};
@@ -1,9 +1,17 @@
#include "stmtnode.hpp"
#include <map>
#include "codegen.hpp"
#include "declnode.hpp"
#include "environ.hpp"
#include "ex.hpp"
#include "exprnode.hpp"
#include "label.hpp"
#include "varnode.hpp"
#include "nodes.hpp" static std::string fileLabel;
#include "std.hpp" static std::map<std::string, std::string> fileMap;
static string fileLabel; StmtNode::StmtNode() : pos(-1) {}
static map<string, string> fileMap;
void StmtNode::debug(int pos, Codegen* g) void StmtNode::debug(int pos, Codegen* g)
{ {
@@ -13,7 +21,11 @@ void StmtNode::debug(int pos, Codegen* g)
} }
} }
void StmtSeqNode::reset(const string& file, const string& lab) void StmtNode::semant(Environ* e) {}
void StmtNode::translate(Codegen* g) {}
void StmtSeqNode::reset(const std::string& file, const std::string& lab)
{ {
fileLabel = ""; fileLabel = "";
fileMap.clear(); fileMap.clear();
@@ -21,6 +33,14 @@ void StmtSeqNode::reset(const string& file, const string& lab)
fileMap[file] = lab; fileMap[file] = lab;
} }
StmtSeqNode::StmtSeqNode(const std::string& f) : file(f) {}
StmtSeqNode::~StmtSeqNode()
{
for (; stmts.size(); stmts.pop_back())
delete stmts.back();
}
//////////////////////// ////////////////////////
// Statement Sequence // // Statement Sequence //
//////////////////////// ////////////////////////
@@ -29,7 +49,7 @@ void StmtSeqNode::semant(Environ* e)
for (int k = 0; k < stmts.size(); ++k) { for (int k = 0; k < stmts.size(); ++k) {
try { try {
stmts[k]->semant(e); stmts[k]->semant(e);
} catch (Ex& x) { } catch (BlitzException& x) {
if (x.pos < 0) if (x.pos < 0)
x.pos = stmts[k]->pos; x.pos = stmts[k]->pos;
if (!x.file.size()) if (!x.file.size())
@@ -41,14 +61,14 @@ void StmtSeqNode::semant(Environ* e)
void StmtSeqNode::translate(Codegen* g) void StmtSeqNode::translate(Codegen* g)
{ {
string t = fileLabel; std::string t = fileLabel;
fileLabel = file.size() ? fileMap[file] : ""; fileLabel = file.size() ? fileMap[file] : "";
for (int k = 0; k < stmts.size(); ++k) { for (int k = 0; k < stmts.size(); ++k) {
StmtNode* stmt = stmts[k]; StmtNode* stmt = stmts[k];
stmt->debug(stmts[k]->pos, g); stmt->debug(stmts[k]->pos, g);
try { try {
stmt->translate(g); stmt->translate(g);
} catch (Ex& x) { } catch (BlitzException& x) {
if (x.pos < 0) if (x.pos < 0)
x.pos = stmts[k]->pos; x.pos = stmts[k]->pos;
if (!x.file.size()) if (!x.file.size())
@@ -59,9 +79,21 @@ void StmtSeqNode::translate(Codegen* g)
fileLabel = t; fileLabel = t;
} }
///////////////// void StmtSeqNode::push_back(StmtNode* s)
// An Include! // {
///////////////// stmts.push_back(s);
}
int StmtSeqNode::size()
{
return stmts.size();
}
// Include
IncludeNode::IncludeNode(const std::string& t, std::shared_ptr<StmtSeqNode> ss) : file(t), stmts(ss) {}
IncludeNode::~IncludeNode() {}
void IncludeNode::semant(Environ* e) void IncludeNode::semant(Environ* e)
{ {
label = genLabel(); label = genLabel();
@@ -78,9 +110,17 @@ void IncludeNode::translate(Codegen* g)
stmts->translate(g); stmts->translate(g);
} }
/////////////////// // Declare Statement
// a declaration // DeclStmtNode::DeclStmtNode(DeclNode* d) : decl(d)
/////////////////// {
pos = d->pos;
}
DeclStmtNode::~DeclStmtNode()
{
delete decl;
}
void DeclStmtNode::semant(Environ* e) void DeclStmtNode::semant(Environ* e)
{ {
decl->proto(e->decls, e); decl->proto(e->decls, e);
@@ -92,15 +132,20 @@ void DeclStmtNode::translate(Codegen* g)
decl->translate(g); decl->translate(g);
} }
////////////////////////////// // Dim Array Statement
// Dim AND declare an Array // DimNode::DimNode(const std::string& i, const std::string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {}
//////////////////////////////
DimNode::~DimNode()
{
delete exprs;
}
void DimNode::semant(Environ* e) void DimNode::semant(Environ* e)
{ {
Type* t = tagType(tag, e); Type* t = tagType(tag, e);
if (Decl* d = e->findDecl(ident)) { if (Decl* d = e->findDecl(ident)) {
ArrayType* a = d->type->arrayType(); ArrayType* a = d->type->arrayType();
if (!a || a->dims != exprs->size() || (t && a->elementType != t)) { if (!a || a->size != exprs->size() || (t && a->type != t)) {
ex("Duplicate identifier"); ex("Duplicate identifier");
} }
sem_type = a; sem_type = a;
@@ -133,7 +178,7 @@ void DimNode::translate(Codegen* g)
return; return;
int et, k; int et, k;
Type* ty = sem_type->arrayType()->elementType; Type* ty = sem_type->arrayType()->type;
if (ty == Type::int_type) if (ty == Type::int_type)
et = 1; et = 1;
else if (ty == Type::float_type) else if (ty == Type::float_type)
@@ -151,6 +196,14 @@ void DimNode::translate(Codegen* g)
g->i_data(0); g->i_data(0);
} }
AssNode::AssNode(VarNode* var, ExprNode* expr) : var(var), expr(expr) {}
AssNode::~AssNode()
{
delete var;
delete expr;
}
//////////////// ////////////////
// Assignment // // Assignment //
//////////////// ////////////////
@@ -170,6 +223,13 @@ void AssNode::translate(Codegen* g)
g->code(var->store(g, expr->translate(g))); g->code(var->store(g, expr->translate(g)));
} }
ExprStmtNode::ExprStmtNode(ExprNode* e) : expr(e) {}
ExprStmtNode::~ExprStmtNode()
{
delete expr;
}
////////////////////////// //////////////////////////
// Expression statement // // Expression statement //
////////////////////////// //////////////////////////
@@ -186,6 +246,8 @@ void ExprStmtNode::translate(Codegen* g)
g->code(t); g->code(t);
} }
LabelNode::LabelNode(const std::string& s, int sz) : ident(s), data_sz(sz) {}
//////////////// ////////////////
// user label // // user label //
//////////////// ////////////////
@@ -206,6 +268,8 @@ void LabelNode::translate(Codegen* g)
g->label("_l" + ident); g->label("_l" + ident);
} }
RestoreNode::RestoreNode(const std::string& i) : ident(i) {}
////////////////// //////////////////
// Restore data // // Restore data //
////////////////// //////////////////
@@ -231,6 +295,8 @@ void RestoreNode::translate(Codegen* g)
g->code(call("__bbRestore", t)); g->code(call("__bbRestore", t));
} }
GotoNode::GotoNode(const std::string& s) : ident(s) {}
//////////////////// ////////////////////
// Goto statement // // Goto statement //
//////////////////// ////////////////////
@@ -247,6 +313,8 @@ void GotoNode::translate(Codegen* g)
g->code(jump("_l" + ident)); g->code(jump("_l" + ident));
} }
GosubNode::GosubNode(const std::string& s) : ident(s) {}
///////////////////// /////////////////////
// Gosub statement // // Gosub statement //
///////////////////// /////////////////////
@@ -264,6 +332,15 @@ void GosubNode::translate(Codegen* g)
g->code(jsr("_l" + ident)); g->code(jsr("_l" + ident));
} }
IfNode::IfNode(ExprNode* e, StmtSeqNode* s, StmtSeqNode* o) : expr(e), stmts(s), elseOpt(o) {}
IfNode::~IfNode()
{
delete expr;
delete stmts;
delete elseOpt;
}
////////////////// //////////////////
// If statement // // If statement //
////////////////// //////////////////
@@ -284,11 +361,11 @@ void IfNode::translate(Codegen* g)
else if (elseOpt) else if (elseOpt)
elseOpt->translate(g); elseOpt->translate(g);
} else { } else {
string _else = genLabel(); std::string _else = genLabel();
g->code(jumpf(expr->translate(g), _else)); g->code(jumpf(expr->translate(g), _else));
stmts->translate(g); stmts->translate(g);
if (elseOpt) { if (elseOpt) {
string _else2 = genLabel(); std::string _else2 = genLabel();
g->code(jump(_else2)); g->code(jump(_else2));
g->label(_else); g->label(_else);
elseOpt->translate(g); elseOpt->translate(g);
@@ -313,21 +390,29 @@ void ExitNode::translate(Codegen* g)
g->code(new TNode(IR_JUMP, 0, 0, sem_brk)); g->code(new TNode(IR_JUMP, 0, 0, sem_brk));
} }
WhileNode::WhileNode(ExprNode* e, StmtSeqNode* s, int wp) : expr(e), stmts(s), wendPos(wp) {}
WhileNode::~WhileNode()
{
delete expr;
delete stmts;
}
///////////////////// /////////////////////
// While statement // // While statement //
///////////////////// /////////////////////
void WhileNode::semant(Environ* e) void WhileNode::semant(Environ* e)
{ {
expr = expr->semant(e); expr = expr->semant(e);
expr = expr->castTo(Type::int_type, e); expr = expr->castTo(Type::int_type, e);
string brk = e->setBreak(sem_brk = genLabel()); std::string brk = e->setBreak(sem_brk = genLabel());
stmts->semant(e); stmts->semant(e);
e->setBreak(brk); e->setBreak(brk);
} }
void WhileNode::translate(Codegen* g) void WhileNode::translate(Codegen* g)
{ {
string loop = genLabel(); std::string loop = genLabel();
if (ConstNode* c = expr->constNode()) { if (ConstNode* c = expr->constNode()) {
if (!c->intValue()) if (!c->intValue())
return; return;
@@ -335,7 +420,7 @@ void WhileNode::translate(Codegen* g)
stmts->translate(g); stmts->translate(g);
g->code(jump(loop)); g->code(jump(loop));
} else { } else {
string cond = genLabel(); std::string cond = genLabel();
g->code(jump(cond)); g->code(jump(cond));
g->label(loop); g->label(loop);
stmts->translate(g); stmts->translate(g);
@@ -381,7 +466,7 @@ void ForNode::semant(Environ* e)
if (!stepExpr->constNode()) if (!stepExpr->constNode())
ex("Step value must be constant"); ex("Step value must be constant");
string brk = e->setBreak(sem_brk = genLabel()); std::string brk = e->setBreak(sem_brk = genLabel());
stmts->semant(e); stmts->semant(e);
e->setBreak(brk); e->setBreak(brk);
} }
@@ -394,8 +479,8 @@ void ForNode::translate(Codegen* g)
//initial assignment //initial assignment
g->code(var->store(g, fromExpr->translate(g))); g->code(var->store(g, fromExpr->translate(g)));
string cond = genLabel(); std::string cond = genLabel();
string loop = genLabel(); std::string loop = genLabel();
g->code(jump(cond)); g->code(jump(cond));
g->label(loop); g->label(loop);
stmts->translate(g); stmts->translate(g);
@@ -415,6 +500,16 @@ void ForNode::translate(Codegen* g)
g->label(sem_brk); g->label(sem_brk);
} }
ForEachNode::ForEachNode(VarNode* v, const std::string& t, StmtSeqNode* s, int np)
: var(v), typeIdent(t), stmts(s), nextPos(np)
{}
ForEachNode::~ForEachNode()
{
delete var;
delete stmts;
}
/////////////////////////////// ///////////////////////////////
// For each object of a type // // For each object of a type //
/////////////////////////////// ///////////////////////////////
@@ -431,17 +526,17 @@ void ForEachNode::semant(Environ* e)
if (t != ty) if (t != ty)
ex("Type mismatch"); ex("Type mismatch");
string brk = e->setBreak(sem_brk = genLabel()); std::string brk = e->setBreak(sem_brk = genLabel());
stmts->semant(e); stmts->semant(e);
e->setBreak(brk); e->setBreak(brk);
} }
void ForEachNode::translate(Codegen* g) void ForEachNode::translate(Codegen* g)
{ {
TNode *t, *l, *r; TNode * t, *l, *r;
string _loop = genLabel(); std::string _loop = genLabel();
string objFirst, objNext; std::string objFirst, objNext;
if (var->isObjParam()) { if (var->isObjParam()) {
objFirst = "__bbObjEachFirst2"; objFirst = "__bbObjEachFirst2";
@@ -466,6 +561,13 @@ void ForEachNode::translate(Codegen* g)
g->label(sem_brk); g->label(sem_brk);
} }
ReturnNode::ReturnNode(ExprNode* e) : expr(e) {}
ReturnNode::~ReturnNode()
{
delete expr;
}
//////////////////////////// ////////////////////////////
// Return from a function // // Return from a function //
//////////////////////////// ////////////////////////////
@@ -508,6 +610,13 @@ void ReturnNode::translate(Codegen* g)
} }
} }
DeleteNode::DeleteNode(ExprNode* e) : expr(e) {}
DeleteNode::~DeleteNode()
{
delete expr;
}
////////////////////// //////////////////////
// Delete statement // // Delete statement //
////////////////////// //////////////////////
@@ -524,6 +633,8 @@ void DeleteNode::translate(Codegen* g)
g->code(call("__bbObjDelete", t)); g->code(call("__bbObjDelete", t));
} }
DeleteEachNode::DeleteEachNode(const std::string& t) : typeIdent(t) {}
/////////////////////////// ///////////////////////////
// Delete each of a type // // Delete each of a type //
/////////////////////////// ///////////////////////////
@@ -539,6 +650,14 @@ void DeleteEachNode::translate(Codegen* g)
g->code(call("__bbObjDeleteEach", global("_t" + typeIdent))); g->code(call("__bbObjDeleteEach", global("_t" + typeIdent)));
} }
InsertNode::InsertNode(ExprNode* e1, ExprNode* e2, bool b) : expr1(e1), expr2(e2), before(b) {}
InsertNode::~InsertNode()
{
delete expr1;
delete expr2;
}
/////////////////////////// ///////////////////////////
// Insert object in list // // Insert object in list //
/////////////////////////// ///////////////////////////
@@ -562,10 +681,26 @@ void InsertNode::translate(Codegen* g)
TNode* t2 = expr2->translate(g); TNode* t2 = expr2->translate(g);
if (g->debug) if (g->debug)
t2 = jumpf(t2, "__bbNullObjEx"); t2 = jumpf(t2, "__bbNullObjEx");
string s = before ? "__bbObjInsBefore" : "__bbObjInsAfter"; std::string s = before ? "__bbObjInsBefore" : "__bbObjInsAfter";
g->code(call(s, t1, t2)); g->code(call(s, t1, t2));
} }
SelectNode::SelectNode(ExprNode* e) : expr(e), defStmts(0), sem_temp(0) {}
SelectNode::~SelectNode()
{
delete expr;
delete defStmts;
delete sem_temp;
for (; cases.size(); cases.pop_back())
delete cases.back();
}
void SelectNode::push_back(CaseNode* c)
{
cases.push_back(c);
}
//////////////////////// ////////////////////////
// A select statement // // A select statement //
//////////////////////// ////////////////////////
@@ -597,8 +732,8 @@ void SelectNode::translate(Codegen* g)
g->code(sem_temp->store(g, expr->translate(g))); g->code(sem_temp->store(g, expr->translate(g)));
vector<string> labs; std::vector<std::string> labs;
string brk = genLabel(); std::string brk = genLabel();
for (k = 0; k < cases.size(); ++k) { for (k = 0; k < cases.size(); ++k) {
CaseNode* c = cases[k]; CaseNode* c = cases[k];
@@ -622,13 +757,21 @@ void SelectNode::translate(Codegen* g)
g->label(brk); g->label(brk);
} }
RepeatNode::RepeatNode(StmtSeqNode* s, ExprNode* e, int up) : stmts(s), expr(e), untilPos(up) {}
RepeatNode::~RepeatNode()
{
delete stmts;
delete expr;
}
//////////////////////////// ////////////////////////////
// Repeat...Until/Forever // // Repeat...Until/Forever //
//////////////////////////// ////////////////////////////
void RepeatNode::semant(Environ* e) void RepeatNode::semant(Environ* e)
{ {
sem_brk = genLabel(); sem_brk = genLabel();
string brk = e->setBreak(sem_brk); std::string brk = e->setBreak(sem_brk);
stmts->semant(e); stmts->semant(e);
e->setBreak(brk); e->setBreak(brk);
if (expr) { if (expr) {
@@ -639,7 +782,7 @@ void RepeatNode::semant(Environ* e)
void RepeatNode::translate(Codegen* g) void RepeatNode::translate(Codegen* g)
{ {
string loop = genLabel(); std::string loop = genLabel();
g->label(loop); g->label(loop);
stmts->translate(g); stmts->translate(g);
debug(untilPos, g); debug(untilPos, g);
@@ -656,6 +799,13 @@ void RepeatNode::translate(Codegen* g)
g->label(sem_brk); g->label(sem_brk);
} }
ReadNode::ReadNode(VarNode* v) : var(v) {}
ReadNode::~ReadNode()
{
delete var;
}
/////////////// ///////////////
// Read data // // Read data //
/////////////// ///////////////
@@ -679,3 +829,11 @@ void ReadNode::translate(Codegen* g)
t = call("__bbReadStr"); t = call("__bbReadStr");
g->code(var->store(g, t)); g->code(var->store(g, t));
} }
CaseNode::CaseNode(ExprSeqNode* e, StmtSeqNode* s) : exprs(e), stmts(s) {}
CaseNode::~CaseNode()
{
delete exprs;
delete stmts;
}
+243
View File
@@ -0,0 +1,243 @@
#pragma once
#include <string>
#include <vector>
#include "node.hpp"
#include "type.hpp"
class Codegen;
class Environ;
struct Decl;
struct Label;
struct DeclNode;
struct ExprSeqNode;
struct ExprNode;
struct StmtNode : public Node {
int pos; //offset in source stream
StmtNode();
void debug(int pos, Codegen* g);
virtual void semant(Environ* e);
virtual void translate(Codegen* g);
};
class StmtSeqNode : public Node {
std::string file;
std::vector<StmtNode*> stmts;
public:
StmtSeqNode(const std::string& f);
~StmtSeqNode();
void semant(Environ* e);
void translate(Codegen* g);
void push_back(StmtNode* s);
int size();
public:
static void reset(const std::string& file, const std::string& lab);
};
class IncludeNode : public StmtNode {
std::string file;
std::string label;
std::shared_ptr<StmtSeqNode> stmts;
public:
IncludeNode(const std::string& t, std::shared_ptr<StmtSeqNode> ss);
~IncludeNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct DeclStmtNode : public StmtNode {
DeclNode* decl;
DeclStmtNode(DeclNode* d);
~DeclStmtNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct DimNode : public StmtNode {
std::string ident, tag;
ExprSeqNode* exprs;
ArrayType* sem_type;
Decl* sem_decl;
DimNode(const std::string& i, const std::string& t, ExprSeqNode* e);
~DimNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct AssNode : public StmtNode {
VarNode* var;
ExprNode* expr;
AssNode(VarNode* var, ExprNode* expr);
~AssNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct ExprStmtNode : public StmtNode {
ExprNode* expr;
ExprStmtNode(ExprNode* e);
~ExprStmtNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct LabelNode : public StmtNode {
std::string ident;
int data_sz;
LabelNode(const std::string& s, int sz);
void semant(Environ* e);
void translate(Codegen* g);
};
struct GotoNode : public StmtNode {
std::string ident;
GotoNode(const std::string& s);
void semant(Environ* e);
void translate(Codegen* g);
};
struct GosubNode : public StmtNode {
std::string ident;
GosubNode(const std::string& s);
void semant(Environ* e);
void translate(Codegen* g);
};
struct IfNode : public StmtNode {
ExprNode* expr;
StmtSeqNode *stmts, *elseOpt;
IfNode(ExprNode* e, StmtSeqNode* s, StmtSeqNode* o);
~IfNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct ExitNode : public StmtNode {
std::string sem_brk;
void semant(Environ* e);
void translate(Codegen* g);
};
struct WhileNode : public StmtNode {
int wendPos;
ExprNode* expr;
StmtSeqNode* stmts;
std::string sem_brk;
WhileNode(ExprNode* e, StmtSeqNode* s, int wp);
~WhileNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct ForNode : public StmtNode {
int nextPos;
VarNode* var;
ExprNode * fromExpr, *toExpr, *stepExpr;
StmtSeqNode* stmts;
std::string sem_brk;
ForNode(VarNode* v, ExprNode* f, ExprNode* t, ExprNode* s, StmtSeqNode* ss, int np);
~ForNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct ForEachNode : public StmtNode {
int nextPos;
VarNode* var;
std::string typeIdent;
StmtSeqNode* stmts;
std::string sem_brk;
ForEachNode(VarNode* v, const std::string& t, StmtSeqNode* s, int np);
~ForEachNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct ReturnNode : public StmtNode {
ExprNode* expr;
std::string returnLabel;
ReturnNode(ExprNode* e);
~ReturnNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct DeleteNode : public StmtNode {
ExprNode* expr;
DeleteNode(ExprNode* e);
~DeleteNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct DeleteEachNode : public StmtNode {
std::string typeIdent;
DeleteEachNode(const std::string& t);
void semant(Environ* e);
void translate(Codegen* g);
};
struct InsertNode : public StmtNode {
ExprNode *expr1, *expr2;
bool before;
InsertNode(ExprNode* e1, ExprNode* e2, bool b);
~InsertNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct CaseNode : public Node {
ExprSeqNode* exprs;
StmtSeqNode* stmts;
CaseNode(ExprSeqNode* e, StmtSeqNode* s);
~CaseNode();
};
struct SelectNode : public StmtNode {
ExprNode* expr;
StmtSeqNode* defStmts;
std::vector<CaseNode*> cases;
VarNode* sem_temp;
SelectNode(ExprNode* e);
~SelectNode();
void push_back(CaseNode* c);
void semant(Environ* e);
void translate(Codegen* g);
};
struct RepeatNode : public StmtNode {
int untilPos;
StmtSeqNode* stmts;
ExprNode* expr;
std::string sem_brk;
RepeatNode(StmtSeqNode* s, ExprNode* e, int up);
~RepeatNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct ReadNode : public StmtNode {
VarNode* var;
ReadNode(VarNode* v);
~ReadNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct RestoreNode : public StmtNode {
std::string ident;
Label* sem_label;
RestoreNode(const std::string& i);
void semant(Environ* e);
void translate(Codegen* g);
};
+10 -10
View File
@@ -1,12 +1,12 @@
#include "toker.hpp" #include "toker.hpp"
#include <cctype> #include <cctype>
#include "ex.hpp" #include "ex.hpp"
#include "std.hpp"
#include <stdutil.hpp>
int Toker::chars_toked; int Toker::chars_toked;
static map<string, int> alphaTokes, lowerTokes; static std::map<std::string, int> alphaTokes, lowerTokes;
static void makeKeywords() static void makeKeywords()
{ {
@@ -81,20 +81,20 @@ static void makeKeywords()
alphaTokes["Shr"] = SHR; alphaTokes["Shr"] = SHR;
alphaTokes["Sar"] = SAR; alphaTokes["Sar"] = SAR;
map<string, int>::const_iterator it; std::map<std::string, int>::const_iterator it;
for (it = alphaTokes.begin(); it != alphaTokes.end(); ++it) { for (it = alphaTokes.begin(); it != alphaTokes.end(); ++it) {
lowerTokes[tolower(it->first)] = it->second; lowerTokes[tolower(it->first)] = it->second;
} }
made = true; made = true;
} }
Toker::Toker(istream& in) : in(in), curr_row(-1) Toker::Toker(std::istream& in) : in(in), curr_row(-1)
{ {
makeKeywords(); makeKeywords();
nextline(); nextline();
} }
map<string, int>& Toker::getKeywords() std::map<std::string, int>& Toker::getKeywords()
{ {
makeKeywords(); makeKeywords();
return alphaTokes; return alphaTokes;
@@ -110,7 +110,7 @@ int Toker::curr()
return tokes[curr_toke].n; return tokes[curr_toke].n;
} }
string Toker::text() std::string Toker::text()
{ {
int from = tokes[curr_toke].from, to = tokes[curr_toke].to; int from = tokes[curr_toke].from, to = tokes[curr_toke].to;
return line.substr(from, to - from); return line.substr(from, to - from);
@@ -186,20 +186,20 @@ void Toker::nextline()
for (++k; isalnum(line[k]) || line[k] == '_'; ++k) { for (++k; isalnum(line[k]) || line[k] == '_'; ++k) {
} }
string ident = tolower(line.substr(from, k - from)); std::string ident = tolower(line.substr(from, k - from));
if (line[k] == ' ' && isalpha(line[k + 1])) { if (line[k] == ' ' && isalpha(line[k + 1])) {
int t = k; int t = k;
for (t += 2; isalnum(line[t]) || line[t] == '_'; ++t) { for (t += 2; isalnum(line[t]) || line[t] == '_'; ++t) {
} }
string s = tolower(line.substr(from, t - from)); std::string s = tolower(line.substr(from, t - from));
if (lowerTokes.find(s) != lowerTokes.end()) { if (lowerTokes.find(s) != lowerTokes.end()) {
k = t; k = t;
ident = s; ident = s;
} }
} }
map<string, int>::iterator it = lowerTokes.find(ident); std::map<std::string, int>::iterator it = lowerTokes.find(ident);
if (it == lowerTokes.end()) { if (it == lowerTokes.end()) {
for (int n = from; n < k; ++n) for (int n = from; n < k; ++n)
+17 -18
View File
@@ -1,12 +1,13 @@
/* /*
The Toker converts an inout stream into tokens for use by the parser. The Toker converts an inout stream into tokens for use by the parser.
*/ */
#pragma once
#ifndef TOKER_H #include <istream>
#define TOKER_H #include <map>
#include <string>
#include <vector>
enum { enum {
DIM = 0x8000, DIM = 0x8000,
@@ -86,28 +87,26 @@ enum {
class Toker { class Toker {
public: public:
Toker(istream& in); Toker(std::istream& in);
int pos(); int pos();
int curr(); int curr();
int next(); int next();
string text(); std::string text();
int lookAhead(int n); int lookAhead(int n);
static int chars_toked; static int chars_toked;
static map<string, int>& getKeywords(); static std::map<std::string, int>& getKeywords();
private: private:
struct Toke { struct Toke {
int n, from, to; int n, from, to;
Toke(int n, int f, int t) : n(n), from(f), to(t) {} Toke(int n, int f, int t) : n(n), from(f), to(t) {}
}; };
istream& in; std::istream& in;
string line; std::string line;
vector<Toke> tokes; std::vector<Toke> tokes;
void nextline(); void nextline();
int curr_row, curr_toke; int curr_row, curr_toke;
}; };
#endif
+184
View File
@@ -0,0 +1,184 @@
#include "type.hpp"
Type::Type() {}
Type::~Type() {}
bool Type::intType()
{
return false;
}
bool Type::floatType()
{
return false;
}
bool Type::stringType()
{
return false;
}
bool Type::canCastTo(std::shared_ptr<Type> t)
{
return this == t.get();
}
std::shared_ptr<FuncType> Type::funcType()
{
return std::shared_ptr<FuncType>();
}
std::shared_ptr<ArrayType> Type::arrayType()
{
return std::shared_ptr<ArrayType>();
}
std::shared_ptr<StructType> Type::structType()
{
return std::shared_ptr<StructType>();
}
std::shared_ptr<ConstType> Type::constType()
{
return std::shared_ptr<ConstType>();
}
std::shared_ptr<VectorType> Type::vectorType()
{
return std::shared_ptr<VectorType>();
}
FuncType::FuncType(std::shared_ptr<Type> return_type, std::shared_ptr<DeclSeq> parameters, bool is_userlib,
bool is_customfunction)
: returnType(return_type), params(parameters), userlib(is_userlib), cfunc(is_customfunction)
{}
FuncType::~FuncType() {}
std::shared_ptr<FuncType> FuncType::funcType()
{
return std::dynamic_pointer_cast<FuncType>(this->shared_from_this());
}
ArrayType::ArrayType(std::shared_ptr<Type> t, int n) : type(t), size(n) {}
ArrayType::~ArrayType() {}
std::shared_ptr<ArrayType> ArrayType::arrayType()
{
return std::dynamic_pointer_cast<ArrayType>(this->shared_from_this());
}
StructType::StructType(const std::string& i) : ident(i) {}
StructType::StructType(const std::string& i, std::shared_ptr<DeclSeq> f) : ident(i), fields(f) {}
StructType::~StructType() {}
std::shared_ptr<StructType> StructType::structType()
{
return std::dynamic_pointer_cast<StructType>(this->shared_from_this());
}
bool StructType::canCastTo(std::shared_ptr<Type> t)
{
return (t.get() == this) || (t == Type::null_type)
|| (this->shared_from_this() == Type::null_type && t->structType());
}
ConstType::ConstType(int32_t n) : intValue(n), valueType(Type::int_type) {}
ConstType::ConstType(float_t n) : floatValue(n), valueType(Type::float_type) {}
ConstType::ConstType(std::string const& n) : stringValue(n), valueType(Type::string_type) {}
ConstType::~ConstType() {}
std::shared_ptr<ConstType> ConstType::constType()
{
return std::dynamic_pointer_cast<ConstType>(this->shared_from_this());
}
VectorType::VectorType(const std::string& l, Type* t, const std::vector<int>& szs)
: label(l), elementType(t), sizes(szs)
{}
VectorType::~VectorType() {}
std::shared_ptr<VectorType> VectorType::vectorType()
{
return std::dynamic_pointer_cast<VectorType>(this->shared_from_this());
}
bool VectorType::canCastTo(std::shared_ptr<Type> t)
{
if (this == t.get()) {
return true;
}
std::shared_ptr<VectorType> v = t->vectorType();
if (!v) {
return false;
}
if (elementType != v->elementType) {
return false;
}
if (sizes.size() != v->sizes.size()) {
return false;
}
for (int k = 0; k < sizes.size(); ++k) {
if (sizes[k] != v->sizes[k]) {
return false;
}
}
return true;
}
class VoidType : public Type {
virtual bool canCastTo(std::shared_ptr<Type> t) override {
return t == Type::void_type;
}
};
std::shared_ptr<Type> Type::void_type = std::make_shared<VoidType>();
class IntType : public Type {
virtual bool intType() override {
return true;
}
virtual bool canCastTo(std::shared_ptr<Type> t) override
{
return t == Type::int_type;
}
};
std::shared_ptr<Type> Type::int_type = std::make_shared<IntType>();
class FloatType : public Type {
virtual bool floatType() override
{
return true;
}
virtual bool canCastTo(std::shared_ptr<Type> t) override
{
return t == Type::float_type;
}
};
std::shared_ptr<Type> Type::float_type = std::make_shared<FloatType>();
class StringType : public Type {
virtual bool stringType() override
{
return true;
}
virtual bool canCastTo(std::shared_ptr<Type> t) override
{
return t == Type::string_type;
}
};
std::shared_ptr<Type> Type::string_type = std::make_shared<StringType>();
std::shared_ptr<Type> Type::string_type = std::make_shared<StructType>("Null");
+110
View File
@@ -0,0 +1,110 @@
#pragma once
#include <cinttypes>
#include <cfloat>
#include <memory>
#include <string>
#include <vector>
#include "decl.hpp"
class FuncType;
class ArrayType;
class StructType;
class ConstType;
class VectorType;
class DeclSeq;
class Type : public std::enable_shared_from_this<Type> {
public:
Type();
virtual ~Type();
virtual bool intType();
virtual bool floatType();
virtual bool stringType();
//operators
virtual bool canCastTo(std::shared_ptr<Type> t);
//casts to inherited types
virtual std::shared_ptr<FuncType> funcType();
virtual std::shared_ptr<ArrayType> arrayType();
virtual std::shared_ptr<StructType> structType();
virtual std::shared_ptr<ConstType> constType();
virtual std::shared_ptr<VectorType> vectorType();
public /* Built-in Types */:
static std::shared_ptr<Type> void_type;
static std::shared_ptr<Type> int_type;
static std::shared_ptr<Type> float_type;
static std::shared_ptr<Type> string_type;
static std::shared_ptr<Type> null_type;
};
class FuncType : public Type {
std::shared_ptr<Type> returnType;
std::shared_ptr<DeclSeq> params;
bool userlib;
bool cfunc;
public:
FuncType(std::shared_ptr<Type> return_type, std::shared_ptr<DeclSeq> parameters, bool is_userlib,
bool is_customfunction);
virtual ~FuncType();
virtual std::shared_ptr<FuncType> funcType() override;
};
class ArrayType : public Type {
std::shared_ptr<Type> type;
int size;
public:
ArrayType(std::shared_ptr<Type> type, int size);
virtual ~ArrayType();
virtual std::shared_ptr<ArrayType> arrayType() override;
};
class StructType : public Type {
std::string ident;
std::shared_ptr<DeclSeq> fields;
public:
StructType(const std::string& name);
StructType(const std::string& name, std::shared_ptr<DeclSeq> fields);
virtual ~StructType();
virtual std::shared_ptr<StructType> structType() override;
virtual bool canCastTo(std::shared_ptr<Type> t) override;
};
class ConstType : public Type {
std::shared_ptr<Type> valueType;
int32_t intValue;
float_t floatValue;
std::string stringValue;
public:
ConstType(int32_t n);
ConstType(float_t n);
ConstType(std::string const& n);
virtual ~ConstType();
virtual std::shared_ptr<ConstType> constType() override;
};
class VectorType : public Type {
std::string label;
Type* elementType;
std::vector<int> sizes;
public:
VectorType(const std::string& l, Type* t, const std::vector<int>& szs);
virtual ~VectorType();
virtual std::shared_ptr<VectorType> vectorType() override;
virtual bool canCastTo(std::shared_ptr<Type> t) override;
};
+1 -5
View File
@@ -1,6 +1,4 @@
#pragma once
#ifndef VAR_H
#define VAR_H
struct Type; struct Type;
@@ -10,5 +8,3 @@ struct Var {
Var(int i, Type* t) : index(i), type(t) {} Var(int i, Type* t) : index(i), type(t) {}
}; };
#endif
@@ -1,6 +1,8 @@
#include "varnode.hpp"
#include "nodes.hpp" #include "codegen.hpp"
#include "std.hpp" #include "environ.hpp"
#include "exprnode.hpp"
#include "type.hpp"
////////////////////////////////// //////////////////////////////////
// Common get/set for variables // // Common get/set for variables //
@@ -28,6 +30,12 @@ bool VarNode::isObjParam()
return false; return false;
} }
DeclVarNode::DeclVarNode(Decl* d) : sem_decl(d)
{
if (d)
sem_type = d->type;
}
////////////////// //////////////////
// Declared var // // Declared var //
////////////////// //////////////////
@@ -54,6 +62,8 @@ bool DeclVarNode::isObjParam()
return sem_type->structType() && sem_decl->kind == DECL_PARAM; return sem_type->structType() && sem_decl->kind == DECL_PARAM;
} }
IdentVarNode::IdentVarNode(const std::string& i, const std::string& t) : ident(i), tag(t) {}
/////////////// ///////////////
// Ident var // // Ident var //
/////////////// ///////////////
@@ -92,11 +102,11 @@ void ArrayVarNode::semant(Environ* e)
if (!sem_decl || !(sem_decl->kind & DECL_ARRAY)) if (!sem_decl || !(sem_decl->kind & DECL_ARRAY))
ex("Array not found"); ex("Array not found");
ArrayType* a = sem_decl->type->arrayType(); ArrayType* a = sem_decl->type->arrayType();
if (t && t != a->elementType) if (t && t != a->type)
ex("array type mismtach"); ex("array type mismtach");
if (a->dims != exprs->size()) if (a->size != exprs->size())
ex("incorrect number of dimensions"); ex("incorrect number of dimensions");
sem_type = a->elementType; sem_type = a->type;
} }
TNode* ArrayVarNode::translate(Codegen* g) TNode* ArrayVarNode::translate(Codegen* g)
@@ -144,6 +154,14 @@ TNode* FieldVarNode::translate(Codegen* g)
return add(t, iconst(sem_field->offset)); return add(t, iconst(sem_field->offset));
} }
VectorVarNode::VectorVarNode(ExprNode* e, ExprSeqNode* es) : expr(e), exprs(es) {}
VectorVarNode::~VectorVarNode()
{
delete expr;
delete exprs;
}
//////////////// ////////////////
// Vector var // // Vector var //
//////////////// ////////////////
@@ -188,3 +206,17 @@ TNode* VectorVarNode::translate(Codegen* g)
} }
return add(t, expr->translate(g)); return add(t, expr->translate(g));
} }
ArrayVarNode::ArrayVarNode(const std::string& i, const std::string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {}
ArrayVarNode::~ArrayVarNode()
{
delete exprs;
}
FieldVarNode::FieldVarNode(ExprNode* e, const std::string& i, const std::string& t) : expr(e), ident(i), tag(t) {}
FieldVarNode::~FieldVarNode()
{
delete expr;
}
@@ -1,8 +1,13 @@
#pragma once
#include <string>
#include "node.hpp"
#include "type.hpp"
#ifndef VARNODE_H class Environ;
#define VARNODE_H class Codegen;
struct TNode;
#include "varnode.hpp" struct ExprNode;
struct ExprSeqNode;
struct VarNode : public Node { struct VarNode : public Node {
Type* sem_type; Type* sem_type;
@@ -17,15 +22,9 @@ struct VarNode : public Node {
virtual TNode* translate(Codegen* g) = 0; virtual TNode* translate(Codegen* g) = 0;
}; };
#include "decl.hpp"
struct DeclVarNode : public VarNode { struct DeclVarNode : public VarNode {
Decl* sem_decl; Decl* sem_decl;
DeclVarNode(Decl* d = 0) : sem_decl(d) DeclVarNode(Decl* d = 0);
{
if (d)
sem_type = d->type;
}
void semant(Environ* e); void semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
virtual TNode* store(Codegen* g, TNode* n); virtual TNode* store(Codegen* g, TNode* n);
@@ -33,33 +32,27 @@ struct DeclVarNode : public VarNode {
}; };
struct IdentVarNode : public DeclVarNode { struct IdentVarNode : public DeclVarNode {
string ident, tag; std::string ident, tag;
IdentVarNode(const string& i, const string& t) : ident(i), tag(t) {} IdentVarNode(const std::string& i, const std::string& t);
void semant(Environ* e); void semant(Environ* e);
}; };
struct ArrayVarNode : public VarNode { struct ArrayVarNode : public VarNode {
string ident, tag; std::string ident, tag;
ExprSeqNode* exprs; ExprSeqNode* exprs;
Decl* sem_decl; Decl* sem_decl;
ArrayVarNode(const string& i, const string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {} ArrayVarNode(const std::string& i, const std::string& t, ExprSeqNode* e);
~ArrayVarNode() ~ArrayVarNode();
{
delete exprs;
}
void semant(Environ* e); void semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
struct FieldVarNode : public VarNode { struct FieldVarNode : public VarNode {
ExprNode* expr; ExprNode* expr;
string ident, tag; std::string ident, tag;
Decl* sem_field; Decl* sem_field;
FieldVarNode(ExprNode* e, const string& i, const string& t) : expr(e), ident(i), tag(t) {} FieldVarNode(ExprNode* e, const std::string& i, const std::string& t);
~FieldVarNode() ~FieldVarNode();
{
delete expr;
}
void semant(Environ* e); void semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
@@ -68,14 +61,8 @@ struct VectorVarNode : public VarNode {
ExprNode* expr; ExprNode* expr;
ExprSeqNode* exprs; ExprSeqNode* exprs;
VectorType* vec_type; VectorType* vec_type;
VectorVarNode(ExprNode* e, ExprSeqNode* es) : expr(e), exprs(es) {} VectorVarNode(ExprNode* e, ExprSeqNode* es);
~VectorVarNode() ~VectorVarNode();
{
delete expr;
delete exprs;
}
void semant(Environ* e); void semant(Environ* e);
TNode* translate(Codegen* g); TNode* translate(Codegen* g);
}; };
#endif
+381
View File
@@ -0,0 +1,381 @@
#include "libs.hpp"
#include <istream>
#include <set>
#include <fstream>
#include <environ.hpp>
#include <linker.hpp>
#include <type.hpp>
#include <config.hpp>
#include <bbruntime_dll.hpp>
#include <prognode.hpp>
#include <windows.h>
int bcc_ver;
int lnk_ver;
int run_ver;
int dbg_ver;
std::string home;
Linker* linkerLib;
Runtime* runtimeLib;
Module* runtimeModule;
Environ* runtimeEnviron;
std::vector<std::string> keyWords;
std::vector<UserFunc> userFuncs;
static HMODULE linkerHMOD, runtimeHMOD;
static Type* bbtypeof(int c)
{
switch (c) {
case '%':
return Type::int_type;
case '#':
return Type::float_type;
case '$':
return Type::string_type;
}
return Type::void_type;
}
static int curr;
static std::string text;
static int bbnext(std::istream& in)
{
text = "";
int t = 0;
for (;;) {
while (isspace(in.peek()))
in.get();
if (in.eof())
return curr = 0;
t = in.get();
if (t != ';')
break;
while (!in.eof() && in.get() != '\n') {
}
}
if (isalpha(t)) {
text += (char)t;
while (isalnum(in.peek()) || in.peek() == '_')
text += (char)in.get();
return curr = -1;
}
if (t == '\"') {
while (in.peek() != '\"')
text = text + (char)in.get();
in.get();
return curr = -2;
}
return curr = t;
}
static const char* linkRuntime()
{
while (const char* sym = runtimeLib->nextSym()) {
std::string s(sym);
int pc = runtimeLib->symValue(sym);
//internal?
if (s[0] == '_') {
runtimeModule->addSymbol(("_" + s).c_str(), pc);
continue;
}
bool cfunc = false;
if (s[0] == '!') {
cfunc = true;
s = s.substr(1);
}
keyWords.push_back(s);
//global!
size_t start = 0, end, k;
Type* t = Type::void_type;
if (!isalpha(s[0])) {
start = 1;
t = bbtypeof(s[0]);
}
for (k = 1; k < s.size(); ++k, end = k) {
if (!isalnum(s[k]) && s[k] != '_')
break;
}
DeclSeq* params = new DeclSeq();
std::string n = s.substr(start, end - start);
while (k < s.size()) {
Type* t = bbtypeof(s[k++]);
int from = k;
for (; isalnum(s[k]) || s[k] == '_'; ++k) {
}
std::string str = s.substr(from, k - from);
ConstType* defType = 0;
if (s[k] == '=') {
int from = ++k;
if (s[k] == '\"') {
for (++k; s[k] != '\"'; ++k) {
}
std::string t = s.substr(from + 1, k - from - 1);
defType = new ConstType(t);
++k;
} else {
if (s[k] == '-')
++k;
for (; isdigit(s[k]); ++k) {
}
if (t == Type::int_type) {
int n = atoi(s.substr(from, k - from));
defType = new ConstType(n);
} else {
float n = (float)atof(s.substr(from, k - from));
defType = new ConstType(n);
}
}
}
Decl* d = params->insertDecl(str, t, DECL_PARAM, defType);
}
FuncType* f = new FuncType(t, params, false, cfunc);
n = tolower(n);
runtimeEnviron->funcDecls->insertDecl(n, f, DECL_FUNC);
runtimeModule->addSymbol(("_f" + n).c_str(), pc);
}
return 0;
}
static std::set<std::string> _ulibkws;
static const char* loadUserLib(const std::string& userlib)
{
std::string t = home + "/userlibs/" + userlib;
std::string lib = "";
std::ifstream in(t.c_str());
bbnext(in);
while (curr) {
if (curr == '.') {
if (bbnext(in) != -1)
return "expecting identifier after '.'";
if (text == "lib") {
if (bbnext(in) != -2)
return "expecting string after lib directive";
lib = text;
} else {
return "unknown decl directive";
}
bbnext(in);
} else if (curr == -1) {
if (!lib.size())
return "function decl without lib directive";
std::string id = text;
std::string lower_id = tolower(id);
if (_ulibkws.count(lower_id))
return "duplicate identifier";
_ulibkws.insert(lower_id);
Type* ty = 0;
switch (bbnext(in)) {
case '%':
ty = Type::int_type;
break;
case '#':
ty = Type::float_type;
break;
case '$':
ty = Type::string_type;
break;
}
if (ty)
bbnext(in);
else
ty = Type::void_type;
DeclSeq* params = new DeclSeq();
if (curr != '(')
return "expecting '(' after function identifier";
bbnext(in);
if (curr != ')') {
for (;;) {
if (curr != -1)
break;
std::string arg = text;
Type* ty = 0;
switch (bbnext(in)) {
case '%':
ty = Type::int_type;
break;
case '#':
ty = Type::float_type;
break;
case '$':
ty = Type::string_type;
break;
case '*':
ty = Type::null_type;
break;
}
if (ty)
bbnext(in);
else
ty = Type::int_type;
ConstType* defType = 0;
Decl* d = params->insertDecl(arg, ty, DECL_PARAM, defType);
if (curr != ',')
break;
bbnext(in);
}
}
if (curr != ')')
return "expecting ')' after function decl";
keyWords.push_back(id);
FuncType* fn = new FuncType(ty, params, true, true);
runtimeEnviron->funcDecls->insertDecl(lower_id, fn, DECL_FUNC);
if (bbnext(in) == ':') { //real name?
bbnext(in);
if (curr != -1 && curr != -2)
return "expecting identifier or string after alias";
id = text;
bbnext(in);
}
userFuncs.push_back(UserFunc(lower_id, id, lib));
}
}
return 0;
}
static const char* linkUserLibs()
{
_ulibkws.clear();
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile((home + "/userlibs/*.decls").c_str(), &fd);
if (h == INVALID_HANDLE_VALUE)
return 0;
const char* err = 0;
do {
if (err = loadUserLib(fd.cFileName)) {
static char buf[64];
sprintf(buf, "Error in userlib '%s' - %s", fd.cFileName, err);
err = buf;
break;
}
} while (FindNextFile(h, &fd));
FindClose(h);
_ulibkws.clear();
return err;
}
const char* openLibs()
{
/*char *p = getenv("blitzpath");
if (!p) return "Can't find blitzpath environment variable";
*/
char* buf = new char[MAX_PATH];
GetModuleFileName(NULL, buf, MAX_PATH);
home = std::string(buf);
delete buf;
std::string::size_type pos = home.find_last_of("\\/");
home = home.substr(0, pos);
linkerHMOD = LoadLibrary((home + "\\linker.dll").c_str());
if (!linkerHMOD)
return "Unable to open linker.dll";
typedef Linker*(_cdecl * GetLinker)();
GetLinker gl = (GetLinker)GetProcAddress(linkerHMOD, "linkerGetLinker");
if (!gl)
return "Error in linker.dll";
linkerLib = gl();
runtimeHMOD = LoadLibrary((home + "\\runtime.dll").c_str());
if (!runtimeHMOD)
return "Unable to open runtime.dll";
typedef Runtime*(_cdecl * GetRuntime)();
GetRuntime gr = (GetRuntime)GetProcAddress(runtimeHMOD, "runtimeGetRuntime");
if (!gr)
return "Error in runtime.dll";
runtimeLib = gr();
bcc_ver = VERSION;
lnk_ver = linkerLib->version();
run_ver = runtimeLib->version();
if ((lnk_ver >> 16) != (bcc_ver >> 16) || (run_ver >> 16) != (bcc_ver >> 16) || (lnk_ver >> 16) != (bcc_ver >> 16))
return "Library version error";
runtimeLib->startup(GetModuleHandle(0));
runtimeModule = linkerLib->createModule();
runtimeEnviron = new Environ("", Type::int_type, 0, 0);
keyWords.clear();
userFuncs.clear();
return 0;
}
const char* linkLibs()
{
if (const char* p = linkRuntime())
return p;
if (const char* p = linkUserLibs())
return p;
return 0;
}
void closeLibs()
{
delete runtimeEnviron;
if (linkerLib)
linkerLib->deleteModule(runtimeModule);
if (runtimeLib)
runtimeLib->shutdown();
if (runtimeHMOD)
FreeLibrary(runtimeHMOD);
if (linkerHMOD)
FreeLibrary(linkerHMOD);
runtimeEnviron = 0;
linkerLib = 0;
runtimeLib = 0;
runtimeHMOD = 0;
linkerHMOD = 0;
}
+31
View File
@@ -0,0 +1,31 @@
#pragma once
#include <string>
#include <vector>
class Linker;
class Runtime;
class Module;
class Environ;
struct UserFunc;
extern int bcc_ver;
extern int lnk_ver;
extern int run_ver;
extern int dbg_ver;
//openLibs
extern std::string home;
extern Linker* linkerLib;
extern Runtime* runtimeLib;
//linkLibs
extern Module* runtimeModule;
extern Environ* runtimeEnviron;
extern std::vector<std::string> keyWords;
extern std::vector<UserFunc> userFuncs;
const char* openLibs();
const char* linkLibs();
void closeLibs();
+338
View File
@@ -0,0 +1,338 @@
#pragma warning(disable : 4786)
#include "libs.hpp"
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <assem_x86/assem_x86.hpp>
#include <bbruntime_dll.hpp>
#include <codegen_x86/codegen_x86.hpp>
#include <config.hpp>
#include <environ.hpp>
#include <ex.hpp>
#include <linker.hpp>
#include <parser.hpp>
#include <stdutil.hpp>
static void showInfo()
{
const int major = (VERSION & 0xffff) / 100, minor = (VERSION & 0xffff) % 100;
std::cout << "BlitzCC V" << major << "." << minor << std::endl;
std::cout << "(C)opyright 2000-2003 Blitz Research Ltd" << std::endl;
}
static void showUsage()
{
std::cout << "Usage: blitzcc [-h|-q|+q|-c|-d|-k|+k|-v|-o exefile] [sourcefile.bb]" << std::endl;
}
static void showHelp()
{
showUsage();
std::cout << "-h : show this help" << std::endl;
std::cout << "-q : quiet mode" << std::endl;
std::cout << "+q : very quiet mode" << std::endl;
std::cout << "-c : compile only" << std::endl;
std::cout << "-d : debug compile" << std::endl;
std::cout << "-k : dump keywords" << std::endl;
std::cout << "+k : dump keywords and syntax" << std::endl;
std::cout << "-v : version info" << std::endl;
std::cout << "-o exefile : generate executable" << std::endl;
}
static void err(const std::string& t)
{
throw std::runtime_error(t);
}
static void usageErr()
{
err("Usage error");
}
static std::string quickHelp(const std::string& kw)
{
Environ* e = runtimeEnviron;
Decl* d = e->funcDecls->findDecl(tolower(kw));
if (!d || d->type->funcType() == 0)
return "No quick help available for " + kw;
std::string t = kw;
FuncType* f = d->type->funcType();
if (f->returnType == Type::float_type)
t += '#';
else if (f->returnType == Type::string_type)
t += '$';
t += " ";
if (f->returnType != Type::void_type)
t += "( ";
for (int k = 0; k < f->params->size(); ++k) {
std::string s;
if (k)
s += ',';
Decl* p = f->params->decls[k];
s += p->name;
if (p->type == Type::float_type)
s += '#';
else if (p->type == Type::string_type)
s += '$';
else if (p->type == Type::void_type)
s += '*';
if (p->defType)
s = '[' + s + ']';
t += s;
}
if (f->returnType != Type::void_type) {
t += f->params->size() ? " )" : ")";
}
return t;
}
static void dumpKeys(bool lang, bool mod, bool help)
{
if (lang) {
std::map<std::string, int>::iterator it;
std::map<std::string, int>& keywords = Toker::getKeywords();
for (it = keywords.begin(); it != keywords.end(); ++it) {
if (it->first.find(' ') != std::string::npos)
continue;
std::cout << it->first << std::endl;
}
}
if (!mod)
return;
for (int k = 0; k < keyWords.size(); ++k) {
std::string t = keyWords[k];
if (t[0] == '_')
continue;
if (!isalpha(t[0]))
t = t.substr(1);
for (int n = 0; n < t.size(); ++n) {
if (!isalnum(t[n]) && t[n] != '_') {
t = t.substr(0, n);
break;
}
}
if (help)
t = quickHelp(t);
std::cout << t << std::endl;
}
}
static std::string verstr(int ver)
{
return itoa((ver & 65535) / 100) + "." + itoa((ver & 65535) % 100);
}
static void versInfo()
{
std::cout << "Compiler version:" << verstr(bcc_ver) << std::endl;
std::cout << "Runtime version:" << verstr(run_ver) << std::endl;
std::cout << "Debugger version:" << verstr(dbg_ver) << std::endl;
std::cout << "Linker version:" << verstr(lnk_ver) << std::endl;
}
int main(int argc, char* argv[])
{
std::shared_ptr<Module> module;
std::shared_ptr<Environ> v_environ;
std::shared_ptr<ProgNode> prog;
try {
std::string in_file, out_file, args;
bool debug = false, quiet = false, veryquiet = false, compileonly = false;
bool dumpkeys = false, dumphelp = false, showhelp = false, dumpasm = false;
bool versinfo = false;
for (int k = 1; k < argc; ++k) {
std::string t = argv[k];
t = tolower(t);
if (t == "-h") {
showhelp = true;
} else if (t == "-a") {
dumpasm = true;
} else if (t == "-q") {
quiet = true;
} else if (t == "+q") {
quiet = veryquiet = true;
} else if (t == "-c") {
compileonly = true;
} else if (t == "-d") {
debug = true;
} else if (t == "-k") {
dumpkeys = true;
} else if (t == "+k") {
dumpkeys = dumphelp = true;
} else if (t == "-v") {
versinfo = true;
} else if (t == "-o") {
if (out_file.size() || k == argc - 1)
usageErr();
out_file = argv[++k];
} else {
if (in_file.size() || t[0] == '-' || t[0] == '+')
usageErr();
in_file = argv[k];
for (++k; k < argc; ++k) {
std::string t = argv[k];
if (t.find(' ') != std::string::npos)
t = '\"' + t + '\"';
if (args.size())
args += ' ';
args += t;
}
}
}
if (out_file.size() && !in_file.size())
usageErr();
if (const char* er = openLibs())
err(er);
if (const char* er = linkLibs())
err(er);
if (showhelp)
showHelp();
if (dumpkeys)
dumpKeys(true, true, dumphelp);
if (versinfo)
versInfo();
if (!in_file.size()) {
return 0;
}
if (in_file[0] == '\"') {
if ((in_file.size() < 3) || (in_file[in_file.size() - 1] != '\"')) {
usageErr();
}
in_file = in_file.substr(1, in_file.size() - 2);
}
std::ifstream in(in_file.c_str());
if (!in)
err("Unable to open input file");
if (!quiet) {
showInfo();
std::cout << "Compiling \"" << in_file << "\"" << std::endl;
}
int n = in_file.rfind('/');
if (n == std::string::npos)
n = in_file.rfind('\\');
if (n != std::string::npos) {
if (!n || in_file[n - 1] == ':')
++n;
SetCurrentDirectory(in_file.substr(0, n).c_str());
}
try {
//parse
if (!veryquiet)
std::cout << "Parsing..." << std::endl;
Toker toker(in);
Parser parser(toker);
prog = parser.parse(in_file);
//semant
if (!veryquiet)
std::cout << "Generating..." << std::endl;
v_environ = prog->semant(runtimeEnviron);
//translate
if (!veryquiet)
std::cout << "Translating..." << std::endl;
qstreambuf qbuf;
std::iostream asmcode(&qbuf);
Codegen_x86 codegen(asmcode, debug);
prog->translate(&codegen, userFuncs);
if (dumpasm) {
std::cout << std::endl << std::string(qbuf.data(), qbuf.size()) << std::endl;
}
//assemble
if (!veryquiet)
std::cout << "Assembling..." << std::endl;
module = linkerLib->createModule();
Assem_x86 assem(asmcode, module);
assem.assemble();
} catch (Ex& x) {
std::string file = '\"' + x.file + '\"';
int row = ((x.pos >> 16) & 65535) + 1, col = (x.pos & 65535) + 1;
std::cout << file << ":" << row << ":" << col << ":" << row << ":" << col << ":" << x.ex << std::endl;
throw std::runtime_error(file);
}
delete prog;
if (out_file.size()) {
if (!veryquiet)
std::cout << "Creating executable \"" << out_file << "\"..." << std::endl;
if (!module->createExe(out_file.c_str(), (home + "/bin/runtime.dll").c_str())) {
err("Error creating executable");
}
} else if (!compileonly) {
void* entry = module->link(runtimeModule);
if (!entry)
return 0;
HMODULE dbgHandle = 0;
/*std::shared_ptr<Debugger> debugger;
if (debug) {
dbgHandle = LoadLibrary((home + "\\debugger.dll").c_str());
if (dbgHandle) {
typedef Debugger*(_cdecl * GetDebugger)(Module*, Environ*);
GetDebugger gd = (GetDebugger)GetProcAddress(dbgHandle, "debuggerGetDebugger");
if (gd)
debugger = gd(module, v_environ);
}
if (!debugger)
err("Error launching debugger");
}*/
if (!veryquiet)
std::cout << "Executing..." << std::endl;
runtimeLib->execute((void (*)())entry, args.c_str(), nullptr);
if (dbgHandle)
FreeLibrary(dbgHandle);
}
delete module;
delete v_environ;
closeLibs();
} catch (std::exception& e) {
std::cout << "Unexpected exception: " << e.what() << std::endl;
} catch (...) {
std::cout << "Unexpected error." << std::endl;
}
std::cin.get();
return 0;
}
-56
View File
@@ -1,56 +0,0 @@
#ifndef NODE_H
#define NODE_H
#include "codegen.hpp"
#include "environ.hpp"
#include "ex.hpp"
#include "toker.hpp"
struct VarNode;
struct ConstNode;
struct Node {
virtual ~Node() {}
//used user funcs...
static set<string> usedfuncs;
//helper funcs
static void ex();
static void ex(const string& e);
static void ex(const string& e, int pos);
static void ex(const string& e, int pos, const string& f);
static string genLabel();
static VarNode* genLocal(Environ* e, Type* ty);
static TNode* compare(int op, TNode* l, TNode* r, Type* ty);
static ConstNode* constValue(Type* ty);
static int enumVars(Environ* e);
static Type* tagType(const string& s, Environ* e);
static TNode* createVars(Environ* e);
static TNode* deleteVars(Environ* e);
static TNode* seq(TNode* l, TNode* r);
static TNode* move(TNode* src, TNode* dest);
static TNode* global(const string& s);
static TNode* local(int offset);
static TNode* arg(int offset);
static TNode* mem(TNode* ref);
static TNode* add(TNode* l, TNode* r);
static TNode* mul(TNode* l, TNode* r);
static TNode* iconst(int n);
static TNode* ret();
static TNode* jsr(const string& s);
static TNode* jump(const string& s);
static TNode* jumpt(TNode* cond, const string& s);
static TNode* jumpf(TNode* cond, const string& s);
static TNode* jumpge(TNode* l, TNode* r, const string& s);
static TNode* call(const string& func, TNode* a0 = 0, TNode* a1 = 0, TNode* a2 = 0);
static TNode* fcall(const string& func, TNode* a0 = 0, TNode* a1 = 0, TNode* a2 = 0);
};
#endif
-64
View File
@@ -1,64 +0,0 @@
/*
The parser builds an abstact syntax tree from input tokens.
*/
#ifndef PARSER_H
#define PARSER_H
#include "nodes.hpp"
#include "toker.hpp"
class Parser {
public:
Parser(Toker& t);
ProgNode* parse(const string& main);
private:
string incfile;
set<string> included;
Toker * toker, *main_toker;
map<string, DimNode*> arrayDecls;
DeclSeqNode* consts;
DeclSeqNode* structs;
DeclSeqNode* funcs;
DeclSeqNode* datas;
StmtSeqNode* parseStmtSeq(int scope);
void parseStmtSeq(StmtSeqNode* stmts, int scope);
void ex(const string& s);
void exp(const string& s);
string parseIdent();
void parseChar(int c);
string parseTypeTag();
VarNode* parseVar();
VarNode* parseVar(const string& ident, const string& tag);
CallNode* parseCall(const string& ident, const string& tag);
IfNode* parseIf();
DeclNode* parseVarDecl(int kind, bool constant);
DimNode* parseArrayDecl();
DeclNode* parseFuncDecl();
DeclNode* parseStructDecl();
ExprSeqNode* parseExprSeq();
ExprNode* parseExpr(bool opt);
ExprNode* parseExpr1(bool opt); //And, Or, Eor
ExprNode* parseExpr2(bool opt); //<,=,>,<=,<>,>=
ExprNode* parseExpr3(bool opt); //+,-
ExprNode* parseExpr4(bool opt); //Lsr,Lsr,Asr
ExprNode* parseExpr5(bool opt); //*,/,Mod
ExprNode* parseExpr6(bool opt); //^
ExprNode* parseUniExpr(bool opt); //+,-,Not,~
ExprNode* parsePrimary(bool opt);
};
#endif
-41
View File
@@ -1,41 +0,0 @@
#ifndef PROGNODE_H
#define PROGNODE_H
#include "codegen.hpp"
#include "node.hpp"
struct UserFunc {
string ident, proc, lib;
UserFunc(const UserFunc& t) : ident(t.ident), proc(t.proc), lib(t.lib) {}
UserFunc(const string& id, const string& pr, const string& lb) : ident(id), proc(pr), lib(lb) {}
};
struct ProgNode : public Node {
DeclSeqNode* consts;
DeclSeqNode* structs;
DeclSeqNode* funcs;
DeclSeqNode* datas;
StmtSeqNode* stmts;
Environ* sem_env;
string file_lab;
ProgNode(DeclSeqNode* c, DeclSeqNode* s, DeclSeqNode* f, DeclSeqNode* d, StmtSeqNode* ss)
: consts(c), structs(s), funcs(f), datas(d), stmts(ss)
{}
~ProgNode()
{
delete consts;
delete structs;
delete funcs;
delete datas;
delete stmts;
}
Environ* semant(Environ* e);
void translate(Codegen* g, const vector<UserFunc>& userfuncs);
};
#endif
-53
View File
@@ -1,53 +0,0 @@
#include "parser.h"
void ExprSeqNode::semant( Scope *s ){
for( int k=0;k<exprs.size();++k ) exprs[k]->semant( s );
type=Type::int_type;
}
void SimpleVarNode::semant( Scope *s ){
if( type=s->findIdent( ident ) ) return;
s->insertIdent( ident,Type::int_type );
}
void LabelNode::semant( Scope *s ){
Type *t=s->findIdent( label );
if( !t ){
s->insertIdent( label,new LabelType( this ) );
return;
}
if( t->labelType() && !t->labelType()->defn ){
t->labelType()->defn=this;
return;
}
semantEx( "Duplicate identifier" );
}
void GotoNode::semant( Scope *s ){
Type *t=s->findIdent( label );
if( !t ){
s->insertIdent( label,new LabelType(0) );
return;
}
if( t->labelType() ) return;
semantEx( "Duplicate Identifier" );
}
void ProgNode::semant( Scope *s ){
StmtSeqNode::semant( s );
map<string,Type*>::iterator it;
for( it=s->idents.begin();it!=s->idents.end();++it ){
if( LabelType *l=it->second->labelType() ){
if( !l->defn ){
semantEx( "Undefined Label" );
}
}
}
}
-2
View File
@@ -1,2 +0,0 @@
#include "std.hpp"
-21
View File
@@ -1,21 +0,0 @@
#ifndef STD_COMPILER_H
#define STD_COMPILER_H
#include "config.hpp"
#include "stdutil.hpp"
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
using namespace std;
#include <windows.h>
#endif
-302
View File
@@ -1,302 +0,0 @@
#ifndef STMTNODE_H
#define STMTNODE_H
#include "node.hpp"
struct StmtNode : public Node {
int pos; //offset in source stream
StmtNode() : pos(-1) {}
void debug(int pos, Codegen* g);
virtual void semant(Environ* e) {}
virtual void translate(Codegen* g) {}
};
struct StmtSeqNode : public Node {
string file;
vector<StmtNode*> stmts;
StmtSeqNode(const string& f) : file(f) {}
~StmtSeqNode()
{
for (; stmts.size(); stmts.pop_back())
delete stmts.back();
}
void semant(Environ* e);
void translate(Codegen* g);
void push_back(StmtNode* s)
{
stmts.push_back(s);
}
int size()
{
return stmts.size();
}
static void reset(const string& file, const string& lab);
};
#include "declnode.hpp"
#include "exprnode.hpp"
struct IncludeNode : public StmtNode {
string file, label;
StmtSeqNode* stmts;
IncludeNode(const string& t, StmtSeqNode* ss) : file(t), stmts(ss) {}
~IncludeNode()
{
delete stmts;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct DeclStmtNode : public StmtNode {
DeclNode* decl;
DeclStmtNode(DeclNode* d) : decl(d)
{
pos = d->pos;
}
~DeclStmtNode()
{
delete decl;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct DimNode : public StmtNode {
string ident, tag;
ExprSeqNode* exprs;
ArrayType* sem_type;
Decl* sem_decl;
DimNode(const string& i, const string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {}
~DimNode()
{
delete exprs;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct AssNode : public StmtNode {
VarNode* var;
ExprNode* expr;
AssNode(VarNode* var, ExprNode* expr) : var(var), expr(expr) {}
~AssNode()
{
delete var;
delete expr;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct ExprStmtNode : public StmtNode {
ExprNode* expr;
ExprStmtNode(ExprNode* e) : expr(e) {}
~ExprStmtNode()
{
delete expr;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct LabelNode : public StmtNode {
string ident;
int data_sz;
LabelNode(const string& s, int sz) : ident(s), data_sz(sz) {}
void semant(Environ* e);
void translate(Codegen* g);
};
struct GotoNode : public StmtNode {
string ident;
GotoNode(const string& s) : ident(s) {}
void semant(Environ* e);
void translate(Codegen* g);
};
struct GosubNode : public StmtNode {
string ident;
GosubNode(const string& s) : ident(s) {}
void semant(Environ* e);
void translate(Codegen* g);
};
struct IfNode : public StmtNode {
ExprNode* expr;
StmtSeqNode *stmts, *elseOpt;
IfNode(ExprNode* e, StmtSeqNode* s, StmtSeqNode* o) : expr(e), stmts(s), elseOpt(o) {}
~IfNode()
{
delete expr;
delete stmts;
delete elseOpt;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct ExitNode : public StmtNode {
string sem_brk;
void semant(Environ* e);
void translate(Codegen* g);
};
struct WhileNode : public StmtNode {
int wendPos;
ExprNode* expr;
StmtSeqNode* stmts;
string sem_brk;
WhileNode(ExprNode* e, StmtSeqNode* s, int wp) : expr(e), stmts(s), wendPos(wp) {}
~WhileNode()
{
delete expr;
delete stmts;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct ForNode : public StmtNode {
int nextPos;
VarNode* var;
ExprNode * fromExpr, *toExpr, *stepExpr;
StmtSeqNode* stmts;
string sem_brk;
ForNode(VarNode* v, ExprNode* f, ExprNode* t, ExprNode* s, StmtSeqNode* ss, int np);
~ForNode();
void semant(Environ* e);
void translate(Codegen* g);
};
struct ForEachNode : public StmtNode {
int nextPos;
VarNode* var;
string typeIdent;
StmtSeqNode* stmts;
string sem_brk;
ForEachNode(VarNode* v, const string& t, StmtSeqNode* s, int np) : var(v), typeIdent(t), stmts(s), nextPos(np) {}
~ForEachNode()
{
delete var;
delete stmts;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct ReturnNode : public StmtNode {
ExprNode* expr;
string returnLabel;
ReturnNode(ExprNode* e) : expr(e) {}
~ReturnNode()
{
delete expr;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct DeleteNode : public StmtNode {
ExprNode* expr;
DeleteNode(ExprNode* e) : expr(e) {}
~DeleteNode()
{
delete expr;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct DeleteEachNode : public StmtNode {
string typeIdent;
DeleteEachNode(const string& t) : typeIdent(t) {}
void semant(Environ* e);
void translate(Codegen* g);
};
struct InsertNode : public StmtNode {
ExprNode *expr1, *expr2;
bool before;
InsertNode(ExprNode* e1, ExprNode* e2, bool b) : expr1(e1), expr2(e2), before(b) {}
~InsertNode()
{
delete expr1;
delete expr2;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct CaseNode : public Node {
ExprSeqNode* exprs;
StmtSeqNode* stmts;
CaseNode(ExprSeqNode* e, StmtSeqNode* s) : exprs(e), stmts(s) {}
~CaseNode()
{
delete exprs;
delete stmts;
}
};
struct SelectNode : public StmtNode {
ExprNode* expr;
StmtSeqNode* defStmts;
vector<CaseNode*> cases;
VarNode* sem_temp;
SelectNode(ExprNode* e) : expr(e), defStmts(0), sem_temp(0) {}
~SelectNode()
{
delete expr;
delete defStmts;
delete sem_temp;
for (; cases.size(); cases.pop_back())
delete cases.back();
}
void push_back(CaseNode* c)
{
cases.push_back(c);
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct RepeatNode : public StmtNode {
int untilPos;
StmtSeqNode* stmts;
ExprNode* expr;
string sem_brk;
RepeatNode(StmtSeqNode* s, ExprNode* e, int up) : stmts(s), expr(e), untilPos(up) {}
~RepeatNode()
{
delete stmts;
delete expr;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct ReadNode : public StmtNode {
VarNode* var;
ReadNode(VarNode* v) : var(v) {}
~ReadNode()
{
delete var;
}
void semant(Environ* e);
void translate(Codegen* g);
};
struct RestoreNode : public StmtNode {
string ident;
Label* sem_label;
RestoreNode(const string& i) : ident(i) {}
void semant(Environ* e);
void translate(Codegen* g);
};
#endif
View File
View File
-65
View File
@@ -1,65 +0,0 @@
struct Node{
};
struct VarNode : public Node{
public Type *semant( Environ *e )=0;
public TNode *translate( Environ *e )=0;
public TNode *evaluate( Environ *e )=0;
};
struct ExprNode : public Node{
public Type *semant( Environ *e )=0;
public TNode *translate( Environ *e )=0;
};
struct ExprSeqNode : public Node{
vector<ExprNode*> exprs;
public Type *semant( Environ *e );
public TNode *translate( Environ *e );
public void push_back( ExprNode *s );
public int size();
};
struct StmtNode : public Node{
public void semant( Environ *e )=0;
public void translate( vector<TNode*> &prog,Environ *e )=0;
};
struct StmtSeqNode : public Node{
vector<StmtNode*> stmts;
public void semant( Environ *e );
public void translate( vector<TNode*> &prog,Environ *e );
public void push_back( StmtNode *s );
public int size();
};
struct DeclNode : public Node{
public void proto( Environ *e )=0;
public void semant( Environ *e )=0;
public void translate( vector<TNode*> &prog,Environ *e )=0;
};
struct DeclSeqNode : public Node{
vector<DeclNode*> decls;
public void proto( Environ *e );
public void semant( Environ *e );
public void translate( vector<TNode*> &prog,Environ *e );
public void push_back( DeclNode *d );
public int size();
};
struct BlockNode : public Node{
DeclSeqNode *decls;
StmtSeqNode *stmts;
public void proto( Environ *e );
public void semant( Environ *e );
public void translate( vector<TNode*> &prog,Environ *e );
};
struct ProgNode : public Node{
BlockNode *block;
public void proto( Environ *e );
public void semant( Environ *e );
public void translate( Environ *e,Codegen &codegen );
};
-74
View File
@@ -1,74 +0,0 @@
#include "type.hpp"
#include "std.hpp"
static struct v_type : public Type {
bool canCastTo(Type* t)
{
return t == Type::void_type;
}
} v;
static struct i_type : public Type {
bool intType()
{
return true;
}
bool canCastTo(Type* t)
{
return t == Type::int_type || t == Type::float_type || t == Type::string_type;
}
} i;
static struct f_type : public Type {
bool floatType()
{
return true;
}
bool canCastTo(Type* t)
{
return t == Type::int_type || t == Type::float_type || t == Type::string_type;
}
} f;
static struct s_type : public Type {
bool stringType()
{
return true;
}
bool canCastTo(Type* t)
{
return t == Type::int_type || t == Type::float_type || t == Type::string_type;
}
} s;
bool StructType::canCastTo(Type* t)
{
return t == this || t == Type::null_type || (this == Type::null_type && t->structType());
}
bool VectorType::canCastTo(Type* t)
{
if (this == t)
return true;
if (VectorType* v = t->vectorType()) {
if (elementType != v->elementType)
return false;
if (sizes.size() != v->sizes.size())
return false;
for (int k = 0; k < sizes.size(); ++k) {
if (sizes[k] != v->sizes[k])
return false;
}
return true;
}
return false;
}
static StructType n("Null");
Type* Type::void_type = &v;
Type* Type::int_type = &i;
Type* Type::float_type = &f;
Type* Type::string_type = &s;
Type* Type::null_type = &n;
-128
View File
@@ -1,128 +0,0 @@
#ifndef TYPE_H
#define TYPE_H
#include "decl.hpp"
struct FuncType;
struct ArrayType;
struct StructType;
struct ConstType;
struct VectorType;
struct Type {
virtual ~Type() {}
virtual bool intType()
{
return 0;
}
virtual bool floatType()
{
return 0;
}
virtual bool stringType()
{
return 0;
}
//casts to inherited types
virtual FuncType* funcType()
{
return 0;
}
virtual ArrayType* arrayType()
{
return 0;
}
virtual StructType* structType()
{
return 0;
}
virtual ConstType* constType()
{
return 0;
}
virtual VectorType* vectorType()
{
return 0;
}
//operators
virtual bool canCastTo(Type* t)
{
return this == t;
}
//built in types
static Type *void_type, *int_type, *float_type, *string_type, *null_type;
};
struct FuncType : public Type {
Type* returnType;
DeclSeq* params;
bool userlib, cfunc;
FuncType(Type* t, DeclSeq* p, bool ulib, bool cfn) : returnType(t), params(p), userlib(ulib), cfunc(cfn) {}
~FuncType()
{
delete params;
}
FuncType* funcType()
{
return this;
}
};
struct ArrayType : public Type {
Type* elementType;
int dims;
ArrayType(Type* t, int n) : elementType(t), dims(n) {}
ArrayType* arrayType()
{
return this;
}
};
struct StructType : public Type {
string ident;
DeclSeq* fields;
StructType(const string& i) : ident(i), fields(0) {}
StructType(const string& i, DeclSeq* f) : ident(i), fields(f) {}
~StructType()
{
delete fields;
}
StructType* structType()
{
return this;
}
virtual bool canCastTo(Type* t);
};
struct ConstType : public Type {
Type* valueType;
int intValue;
float floatValue;
string stringValue;
ConstType(int n) : intValue(n), valueType(Type::int_type) {}
ConstType(float n) : floatValue(n), valueType(Type::float_type) {}
ConstType(const string& n) : stringValue(n), valueType(Type::string_type) {}
ConstType* constType()
{
return this;
}
};
struct VectorType : public Type {
string label;
Type* elementType;
vector<int> sizes;
VectorType(const string& l, Type* t, const vector<int>& szs) : label(l), elementType(t), sizes(szs) {}
VectorType* vectorType()
{
return this;
}
virtual bool canCastTo(Type* t);
};
#endif