compiler: Move and modernize
compiler is blitzcc, what I previously called compiler is now compiler_lib
This commit is contained in:
+33
-37
@@ -1,45 +1,24 @@
|
||||
project(compiler)
|
||||
|
||||
add_library(${PROJECT_NAME} MODULE
|
||||
"assem.hpp"
|
||||
"codegen.hpp"
|
||||
"compiler.cpp"
|
||||
"compiler.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"
|
||||
"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_subdirectory(lib)
|
||||
add_subdirectory(gen)
|
||||
|
||||
set(PRIVATE_SOURCE
|
||||
"main.cpp"
|
||||
"libs.cpp"
|
||||
"libs.hpp"
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
${PRIVATE_SOURCE}
|
||||
)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "blitzcc")
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
config
|
||||
stdutil
|
||||
compiler_lib
|
||||
linker
|
||||
runtime
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
@@ -96,3 +75,20 @@ if (WIN32)
|
||||
NOINOUT
|
||||
)
|
||||
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()
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 );
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
@@ -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]
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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,19 +1,16 @@
|
||||
/* BlitzPC assembler.
|
||||
This REALLY needs some work - very slow. */
|
||||
|
||||
/*
|
||||
|
||||
BlitzPC assembler.
|
||||
|
||||
This REALLY needs some work - very slow.
|
||||
|
||||
*/
|
||||
|
||||
#include "assem_x86.h"
|
||||
#include "../ex.h"
|
||||
#include "../std.h"
|
||||
#include "assem_x86.hpp"
|
||||
#include <map>
|
||||
#include "../ex.hpp"
|
||||
#include "insts.hpp"
|
||||
#include "operand.hpp"
|
||||
#include <istream>
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
typedef map<string, Inst*> InstMap;
|
||||
typedef std::map<std::string, Inst*> InstMap;
|
||||
typedef InstMap::value_type InstPair;
|
||||
typedef InstMap::const_iterator InstIter;
|
||||
|
||||
@@ -21,7 +18,7 @@ static InstMap instMap;
|
||||
|
||||
//#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.
|
||||
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")
|
||||
return 0;
|
||||
@@ -100,7 +97,7 @@ void Assem_x86::emitd(int n)
|
||||
void Assem_x86::emitImm(const Operand& o, int 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) {
|
||||
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);
|
||||
op.parse();
|
||||
if (!(op.mode & IMM))
|
||||
throw Ex("operand must be immediate");
|
||||
throw BlitzException("operand must be immediate");
|
||||
emitImm(op, size);
|
||||
}
|
||||
|
||||
void Assem_x86::r_reloc(const string& s)
|
||||
void Assem_x86::r_reloc(const std::string& s)
|
||||
{
|
||||
if (!s.size())
|
||||
return;
|
||||
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())
|
||||
return;
|
||||
mod->addReloc(s.c_str(), mod->getPC(), false);
|
||||
}
|
||||
|
||||
void Assem_x86::assemInst(const string& name, const string& lhs, const string& rhs)
|
||||
void Assem_x86::assemInst(const std::string& name, const std::string& lhs, const std::string& rhs)
|
||||
{
|
||||
//parse operands
|
||||
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 (!(lop.mode & inst->lmode) || !(rop.mode & inst->rmode))
|
||||
throw Ex("illegal addressing mode");
|
||||
throw BlitzException("illegal addressing mode");
|
||||
} else {
|
||||
InstIter it = instMap.find(name);
|
||||
if (it == instMap.end())
|
||||
throw Ex("unrecognized instruction");
|
||||
throw BlitzException("unrecognized instruction");
|
||||
inst = it->second;
|
||||
for (;;) {
|
||||
if ((lop.mode & inst->lmode) && (rop.mode & inst->rmode))
|
||||
break;
|
||||
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())
|
||||
throw Ex("operand error");
|
||||
throw BlitzException("operand error");
|
||||
|
||||
if (name == ".db") {
|
||||
if (op[0] != '\"')
|
||||
emitImm(op, 1);
|
||||
else {
|
||||
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)
|
||||
emit(op[k]);
|
||||
}
|
||||
@@ -314,26 +311,26 @@ void Assem_x86::assemDir(const string& name, const string& op)
|
||||
Operand o(op);
|
||||
o.parse();
|
||||
if (!(o.mode & IMM))
|
||||
throw Ex("operand must be immediate");
|
||||
throw BlitzException("operand must be immediate");
|
||||
align(o.imm);
|
||||
} 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;
|
||||
string name;
|
||||
vector<string> ops;
|
||||
std::string name;
|
||||
std::vector<std::string> ops;
|
||||
|
||||
//label?
|
||||
if (!isspace(line[i])) {
|
||||
while (!isspace(line[i]))
|
||||
++i;
|
||||
string lab = line.substr(0, i);
|
||||
std::string lab = line.substr(0, i);
|
||||
if (!mod->addSymbol(lab.c_str(), mod->getPC()))
|
||||
throw Ex("duplicate label");
|
||||
throw BlitzException("duplicate label");
|
||||
}
|
||||
|
||||
//skip space
|
||||
@@ -360,7 +357,7 @@ void Assem_x86::assemLine(const string& line)
|
||||
for (++i; line[i] != '\"' && line[i] != '\n'; ++i) {
|
||||
}
|
||||
if (line[i++] != '\"')
|
||||
throw Ex("missing close quote");
|
||||
throw BlitzException("missing close quote");
|
||||
} else {
|
||||
for (++i; line[i] != ',' && line[i] != ';' && line[i] != '\n'; ++i) {
|
||||
}
|
||||
@@ -378,7 +375,7 @@ void Assem_x86::assemLine(const string& line)
|
||||
break;
|
||||
|
||||
if (line[i++] != ',')
|
||||
throw Ex("expecting ','");
|
||||
throw BlitzException("expecting ','");
|
||||
}
|
||||
|
||||
//pseudo op?
|
||||
@@ -390,7 +387,7 @@ void Assem_x86::assemLine(const string& line)
|
||||
|
||||
//normal instruction!
|
||||
if (ops.size() > 2)
|
||||
throw Ex("Too many operands");
|
||||
throw BlitzException("Too many operands");
|
||||
ops.push_back("");
|
||||
ops.push_back("");
|
||||
assemInst(name, ops[0], ops[1]);
|
||||
@@ -398,11 +395,11 @@ void Assem_x86::assemLine(const string& line)
|
||||
|
||||
void Assem_x86::assemble()
|
||||
{
|
||||
string line;
|
||||
std::string line;
|
||||
|
||||
while (!in.eof()) {
|
||||
try {
|
||||
getline(in, line);
|
||||
std::getline(in, line);
|
||||
line += '\n';
|
||||
#ifdef LOG
|
||||
clog << line;
|
||||
@@ -411,8 +408,8 @@ void Assem_x86::assemble()
|
||||
#ifdef LOG
|
||||
clog << endl;
|
||||
#endif
|
||||
} catch (Ex& x) {
|
||||
throw Ex(line + x.ex);
|
||||
} catch (BlitzException& x) {
|
||||
throw BlitzException(line + x.ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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 @@
|
||||
|
||||
#ifndef INSTS_H
|
||||
#define INSTS_H
|
||||
|
||||
#pragma once
|
||||
//operand addressing modes
|
||||
enum{
|
||||
REG=0x0001,REG8=0x0002,REG16=0x0004,REG32=0x0008,
|
||||
@@ -33,5 +30,3 @@ struct Inst{
|
||||
};
|
||||
|
||||
extern Inst insts[];
|
||||
|
||||
#endif
|
||||
@@ -1,25 +1,25 @@
|
||||
|
||||
#include "operand.h"
|
||||
#include "../ex.h"
|
||||
#include "../std.h"
|
||||
#include "insts.h"
|
||||
#include "operand.hpp"
|
||||
#include "../ex.hpp"
|
||||
#include "insts.hpp"
|
||||
|
||||
static const char* regs[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", "ax", "cx", "dx", "bx",
|
||||
"sp", "bp", "si", "di", "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
|
||||
|
||||
static void opError()
|
||||
{
|
||||
throw Ex("error in operand");
|
||||
throw BlitzException("error in operand");
|
||||
}
|
||||
|
||||
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(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)
|
||||
{
|
||||
@@ -55,7 +55,7 @@ bool Operand::parseReg(int* reg)
|
||||
}
|
||||
if (!i)
|
||||
return false;
|
||||
string t = s.substr(0, i);
|
||||
std::string t = s.substr(0, i);
|
||||
for (int j = 0; j < 24; ++j) {
|
||||
if (t == regs[j]) {
|
||||
*reg = j;
|
||||
@@ -80,7 +80,7 @@ bool Operand::parseFPReg(int* reg)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Operand::parseLabel(string* label)
|
||||
bool Operand::parseLabel(std::string* label)
|
||||
{
|
||||
if (!s.size() || (!isalpha(s[0]) && s[0] != '_'))
|
||||
return false;
|
||||
@@ -182,10 +182,10 @@ void Operand::parse()
|
||||
|
||||
for (;;) {
|
||||
int n;
|
||||
string l;
|
||||
std::string l;
|
||||
if (parseReg(&n)) {
|
||||
if (n < 16)
|
||||
throw Ex("register must be 32 bit");
|
||||
throw BlitzException("register must be 32 bit");
|
||||
n &= 7;
|
||||
if (parseChar('*')) {
|
||||
if (n == 4)
|
||||
@@ -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 @@
|
||||
|
||||
#ifndef CODEGEN_H
|
||||
#define CODEGEN_H
|
||||
|
||||
#include "std.hpp"
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
|
||||
enum {
|
||||
IR_JUMP,
|
||||
@@ -62,11 +60,11 @@ struct TNode {
|
||||
int op; //opcode
|
||||
TNode *l, *r; //args
|
||||
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, 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()
|
||||
{
|
||||
delete l;
|
||||
@@ -78,19 +76,17 @@ struct TNode {
|
||||
|
||||
class Codegen {
|
||||
public:
|
||||
ostream& out;
|
||||
std::ostream& out;
|
||||
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 leave(TNode* cleanup, int pop_sz) = 0;
|
||||
virtual void label(const string& l) = 0;
|
||||
virtual void i_data(int i, const string& l = "") = 0;
|
||||
virtual void s_data(const string& s, const string& l = "") = 0;
|
||||
virtual void p_data(const string& p, const string& l = "") = 0;
|
||||
virtual void label(const std::string& l) = 0;
|
||||
virtual void i_data(int i, const std::string& l = "") = 0;
|
||||
virtual void s_data(const std::string& s, const std::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 flush() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,135 @@
|
||||
#include "codegen_x86.hpp"
|
||||
#include "tile.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "codegen_x86.h"
|
||||
#include "../std.h"
|
||||
#include "tile.h"
|
||||
#include <stdutil.hpp>
|
||||
|
||||
//#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)) : "";
|
||||
}
|
||||
@@ -50,7 +172,7 @@ static bool getShift(int n, int& shift)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool matchMEM(TNode* t, string& s)
|
||||
static bool matchMEM(TNode* t, std::string& s)
|
||||
{
|
||||
#ifdef NOOPTS
|
||||
return false;
|
||||
@@ -73,7 +195,7 @@ static bool matchMEM(TNode* t, string& s)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool matchCONST(TNode* t, string& s)
|
||||
static bool matchCONST(TNode* t, std::string& s)
|
||||
{
|
||||
#ifdef NOOPTS
|
||||
return false;
|
||||
@@ -90,7 +212,7 @@ static bool matchCONST(TNode* t, string& s)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool matchMEMCONST(TNode* t, string& s)
|
||||
static bool matchMEMCONST(TNode* t, std::string& s)
|
||||
{
|
||||
#ifdef NOOPTS
|
||||
return false;
|
||||
@@ -99,7 +221,7 @@ static bool matchMEMCONST(TNode* t, string& s)
|
||||
return matchMEM(t, s) || matchCONST(t, s);
|
||||
}
|
||||
|
||||
Tile* Codegen_x86::genCompare(TNode* t, string& func, bool negate)
|
||||
Tile* Codegen_x86::genCompare(TNode* t, std::string& func, bool negate)
|
||||
{
|
||||
switch (t->op) {
|
||||
case IR_SETEQ:
|
||||
@@ -124,7 +246,7 @@ Tile* Codegen_x86::genCompare(TNode* t, string& func, bool negate)
|
||||
return 0;
|
||||
}
|
||||
|
||||
string q, m, c;
|
||||
std::string q, m, c;
|
||||
TNode *ql = 0, *qr = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
string s;
|
||||
std::string s;
|
||||
switch (t->op) {
|
||||
case IR_NEG:
|
||||
s = "\tneg\t%l\n";
|
||||
@@ -166,7 +288,7 @@ Tile* Codegen_x86::munchUnary(TNode* t)
|
||||
|
||||
Tile* Codegen_x86::munchLogical(TNode* t)
|
||||
{
|
||||
string s;
|
||||
std::string s;
|
||||
switch (t->op) {
|
||||
case IR_AND:
|
||||
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) {
|
||||
case IR_ADD:
|
||||
op = "\tadd\t";
|
||||
@@ -238,7 +360,7 @@ Tile* Codegen_x86::munchArith(TNode* t)
|
||||
|
||||
Tile* Codegen_x86::munchShift(TNode* t)
|
||||
{
|
||||
string s, op;
|
||||
std::string s, op;
|
||||
switch (t->op) {
|
||||
case IR_SHL:
|
||||
op = "\tshl\t";
|
||||
@@ -264,7 +386,7 @@ Tile* Codegen_x86::munchShift(TNode* t)
|
||||
|
||||
Tile* Codegen_x86::munchRelop(TNode* t)
|
||||
{
|
||||
string func;
|
||||
std::string func;
|
||||
Tile* q = genCompare(t, func, false);
|
||||
|
||||
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)
|
||||
{
|
||||
string s;
|
||||
std::string s;
|
||||
switch (t->op) {
|
||||
case IR_FNEG:
|
||||
s = "\tfchs\n";
|
||||
@@ -290,7 +412,7 @@ Tile* Codegen_x86::munchFPUnary(TNode* t)
|
||||
|
||||
Tile* Codegen_x86::munchFPArith(TNode* t)
|
||||
{
|
||||
string s, s2;
|
||||
std::string s, s2;
|
||||
switch (t->op) {
|
||||
case IR_FADD:
|
||||
s = "\tfaddp\tst(1)\n";
|
||||
@@ -314,7 +436,7 @@ Tile* Codegen_x86::munchFPArith(TNode* t)
|
||||
|
||||
Tile* Codegen_x86::munchFPRelop(TNode* t)
|
||||
{
|
||||
string s, s2;
|
||||
std::string s, s2;
|
||||
switch (t->op) {
|
||||
case IR_FSETEQ:
|
||||
s = "z";
|
||||
@@ -375,7 +497,7 @@ Tile* Codegen_x86::munch(TNode* t)
|
||||
if (!t)
|
||||
return 0;
|
||||
Tile* q = 0;
|
||||
string s;
|
||||
std::string s;
|
||||
switch (t->op) {
|
||||
case IR_JSR:
|
||||
q = new Tile("\tcall\t" + t->sconst + '\n');
|
||||
@@ -404,7 +526,7 @@ Tile* Codegen_x86::munch(TNode* t)
|
||||
if (TNode* p = t->l) {
|
||||
bool neg = false;
|
||||
if (isRelop(p->op)) {
|
||||
string func;
|
||||
std::string func;
|
||||
q = genCompare(p, func, neg);
|
||||
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) {
|
||||
bool neg = true;
|
||||
if (isRelop(p->op)) {
|
||||
string func;
|
||||
std::string func;
|
||||
q = genCompare(p, func, neg);
|
||||
q = new Tile("\tj" + func + "\t" + t->sconst + "\n", q);
|
||||
}
|
||||
@@ -422,7 +544,7 @@ Tile* Codegen_x86::munch(TNode* t)
|
||||
break;
|
||||
case IR_MOVE:
|
||||
if (matchMEM(t->r, s)) {
|
||||
string c;
|
||||
std::string c;
|
||||
if (matchCONST(t->l, c)) {
|
||||
q = new Tile("\tmov\t" + s + "," + c + "\n");
|
||||
} 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))
|
||||
p = t->l->l;
|
||||
if (p) {
|
||||
string c, op;
|
||||
std::string c, op;
|
||||
switch (t->l->op) {
|
||||
case IR_ADD:
|
||||
op = "\tadd\t";
|
||||
@@ -466,7 +588,7 @@ Tile* Codegen_x86::munchReg(TNode* t)
|
||||
if (!t)
|
||||
return 0;
|
||||
|
||||
string s;
|
||||
std::string s;
|
||||
Tile* q = 0;
|
||||
|
||||
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");
|
||||
break;
|
||||
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;
|
||||
case IR_CAST:
|
||||
q = munchFP(t->l);
|
||||
@@ -570,7 +692,7 @@ Tile* Codegen_x86::munchFP(TNode* t)
|
||||
if (!t)
|
||||
return 0;
|
||||
|
||||
string s;
|
||||
std::string s;
|
||||
Tile* q = 0;
|
||||
|
||||
switch (t->op) {
|
||||
@@ -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 "../std.h"
|
||||
#include "codegen_x86.h"
|
||||
#include <stdutil.hpp>
|
||||
|
||||
//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
|
||||
static bool regUsed[NUM_REGS + 1];
|
||||
bool regUsed[NUM_REGS + 1];
|
||||
|
||||
//size of locals in function
|
||||
static int frameSize, maxFrameSize;
|
||||
int frameSize, maxFrameSize;
|
||||
|
||||
//code fragments
|
||||
static vector<string> codeFrags, dataFrags;
|
||||
std::vector<std::string> codeFrags, dataFrags;
|
||||
|
||||
//name of function
|
||||
static string funcLabel;
|
||||
std::string funcLabel;
|
||||
|
||||
static void resetRegs()
|
||||
void resetRegs()
|
||||
{
|
||||
for (int n = 1; n <= NUM_REGS; ++n)
|
||||
regUsed[n] = false;
|
||||
}
|
||||
|
||||
static int allocReg(int n)
|
||||
int allocReg(int n)
|
||||
{
|
||||
if (!n || regUsed[n]) {
|
||||
for (n = NUM_REGS; n >= 1 && regUsed[n]; --n) {
|
||||
@@ -50,7 +51,7 @@ static void pushReg(int n)
|
||||
maxFrameSize = frameSize;
|
||||
char buff[32];
|
||||
_itoa(frameSize, buff, 10);
|
||||
string s = "\tmov\t[ebp-";
|
||||
std::string s = "\tmov\t[ebp-";
|
||||
s += buff;
|
||||
s += "],";
|
||||
s += regs[n];
|
||||
@@ -62,7 +63,7 @@ static void popReg(int n)
|
||||
{
|
||||
char buff[32];
|
||||
_itoa(frameSize, buff, 10);
|
||||
string s = "\tmov\t";
|
||||
std::string s = "\tmov\t";
|
||||
s += regs[n];
|
||||
s += ",[ebp-";
|
||||
s += buff;
|
||||
@@ -73,21 +74,21 @@ static void popReg(int n)
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{}
|
||||
|
||||
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)
|
||||
{}
|
||||
|
||||
@@ -144,7 +145,7 @@ int Tile::eval(int want)
|
||||
if (want_l)
|
||||
want = want_l;
|
||||
|
||||
string* as = &assem;
|
||||
std::string* as = &assem;
|
||||
|
||||
if (!l) {
|
||||
got_l = allocReg(want);
|
||||
@@ -186,9 +187,9 @@ int Tile::eval(int want)
|
||||
moveReg(want_r, got_r);
|
||||
|
||||
int i;
|
||||
while ((i = as->find("%l")) != string::npos)
|
||||
while ((i = as->find("%l")) != std::string::npos)
|
||||
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]);
|
||||
|
||||
codeFrags.push_back(*as);
|
||||
@@ -213,129 +214,9 @@ int Tile::eval(int want)
|
||||
return got_l;
|
||||
}
|
||||
|
||||
void Codegen_x86::flush()
|
||||
{
|
||||
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)
|
||||
std::string fixEsp(int esp_off)
|
||||
{
|
||||
if (esp_off < 0)
|
||||
return "\tsub\tesp," + itoa(-esp_off) + "\n";
|
||||
return "\tadd\tesp," + itoa(esp_off) + "\n";
|
||||
}
|
||||
|
||||
void Codegen_x86::leave(TNode* cleanup, int pop_sz)
|
||||
{
|
||||
if (cleanup) {
|
||||
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');
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
#include "decl.hpp"
|
||||
#include "std.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() {}
|
||||
|
||||
DeclSeq::DeclSeq() {}
|
||||
@@ -20,9 +20,9 @@ DeclSeq::~DeclSeq()
|
||||
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) {
|
||||
if ((*it)->name == s)
|
||||
return *it;
|
||||
@@ -30,10 +30,15 @@ Decl* DeclSeq::findDecl(const string& s)
|
||||
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))
|
||||
return 0;
|
||||
decls.push_back(new Decl(s, t, kind, d));
|
||||
return decls.back();
|
||||
}
|
||||
|
||||
int DeclSeq::size()
|
||||
{
|
||||
return decls.size();
|
||||
}
|
||||
@@ -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 "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 //
|
||||
@@ -10,7 +26,7 @@ void DeclSeqNode::proto(DeclSeq* d, Environ* e)
|
||||
for (size_t k = 0; k < decls.size(); ++k) {
|
||||
try {
|
||||
decls[k]->proto(d, e);
|
||||
} catch (Ex& x) {
|
||||
} catch (BlitzException& x) {
|
||||
if (x.pos < 0)
|
||||
x.pos = decls[k]->pos;
|
||||
if (!x.file.size())
|
||||
@@ -25,7 +41,7 @@ void DeclSeqNode::semant(Environ* e)
|
||||
for (size_t k = 0; k < decls.size(); ++k) {
|
||||
try {
|
||||
decls[k]->semant(e);
|
||||
} catch (Ex& x) {
|
||||
} catch (BlitzException& x) {
|
||||
if (x.pos < 0)
|
||||
x.pos = decls[k]->pos;
|
||||
if (!x.file.size())
|
||||
@@ -40,7 +56,7 @@ void DeclSeqNode::translate(Codegen* g)
|
||||
for (size_t k = 0; k < decls.size(); ++k) {
|
||||
try {
|
||||
decls[k]->translate(g);
|
||||
} catch (Ex& x) {
|
||||
} catch (BlitzException& x) {
|
||||
if (x.pos < 0)
|
||||
x.pos = decls[k]->pos;
|
||||
if (!x.file.size())
|
||||
@@ -55,7 +71,7 @@ void DeclSeqNode::transdata(Codegen* g)
|
||||
for (size_t k = 0; k < decls.size(); ++k) {
|
||||
try {
|
||||
decls[k]->transdata(g);
|
||||
} catch (Ex& x) {
|
||||
} catch (BlitzException& x) {
|
||||
if (x.pos < 0)
|
||||
x.pos = decls[k]->pos;
|
||||
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 //
|
||||
////////////////////////////
|
||||
@@ -131,6 +167,16 @@ void VarDeclNode::translate(Codegen* 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 //
|
||||
//////////////////////////
|
||||
@@ -177,7 +223,7 @@ void FuncDeclNode::translate(Codegen* g)
|
||||
if (t)
|
||||
g->code(t);
|
||||
if (g->debug) {
|
||||
string t = genLabel();
|
||||
std::string t = genLabel();
|
||||
g->s_data(ident, 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);
|
||||
}
|
||||
|
||||
StructDeclNode::StructDeclNode(const std::string& i, DeclSeqNode* f) : ident(i), fields(f) {}
|
||||
|
||||
StructDeclNode::~StructDeclNode()
|
||||
{
|
||||
delete fields;
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// Type Declaration //
|
||||
//////////////////////
|
||||
@@ -230,7 +283,7 @@ void StructDeclNode::translate(Codegen* g)
|
||||
//used and free lists for type
|
||||
int k;
|
||||
for (k = 0; k < 2; ++k) {
|
||||
string lab = genLabel();
|
||||
std::string lab = genLabel();
|
||||
g->i_data(0, lab); //fields
|
||||
g->p_data(lab); //next
|
||||
g->p_data(lab); //prev
|
||||
@@ -245,7 +298,7 @@ void StructDeclNode::translate(Codegen* g)
|
||||
for (k = 0; k < sem_type->fields->size(); ++k) {
|
||||
Decl* field = sem_type->fields->decls[k];
|
||||
Type* type = field->type;
|
||||
string t;
|
||||
std::string t;
|
||||
if (type == Type::int_type)
|
||||
t = "__bbIntType";
|
||||
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 //
|
||||
//////////////////////
|
||||
@@ -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 //
|
||||
////////////////////////
|
||||
@@ -308,7 +377,7 @@ void VectorDeclNode::proto(DeclSeq* d, Environ* env)
|
||||
if (!ty)
|
||||
ty = Type::int_type;
|
||||
|
||||
vector<int> sizes;
|
||||
std::vector<int> sizes;
|
||||
for (int k = 0; k < exprs->size(); ++k) {
|
||||
ExprNode* e = exprs->exprs[k] = exprs->exprs[k]->semant(env);
|
||||
ConstNode* c = e->constNode();
|
||||
@@ -319,7 +388,7 @@ void VectorDeclNode::proto(DeclSeq* d, Environ* env)
|
||||
ex("Blitz array sizes must not be negative");
|
||||
sizes.push_back(n + 1);
|
||||
}
|
||||
string label = genLabel();
|
||||
std::string label = genLabel();
|
||||
sem_type = new VectorType(label, ty, sizes);
|
||||
if (!d->insertDecl(ident, sem_type, kind)) {
|
||||
delete sem_type;
|
||||
@@ -338,7 +407,7 @@ void VectorDeclNode::translate(Codegen* g)
|
||||
for (size_t k = 0; k < v->sizes.size(); ++k)
|
||||
sz *= v->sizes[k];
|
||||
g->i_data(sz);
|
||||
string t;
|
||||
std::string t;
|
||||
Type* type = v->elementType;
|
||||
if (type == Type::int_type)
|
||||
t = "__bbIntType";
|
||||
@@ -355,3 +424,13 @@ void VectorDeclNode::translate(Codegen* g)
|
||||
if (kind == DECL_GLOBAL)
|
||||
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) {}
|
||||
@@ -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 "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();
|
||||
typeDecls = new DeclSeq();
|
||||
@@ -29,7 +30,7 @@ Environ::~Environ()
|
||||
delete types[k];
|
||||
}
|
||||
|
||||
Decl* Environ::findDecl(const string& s)
|
||||
Decl* Environ::findDecl(const std::string& s)
|
||||
{
|
||||
for (Environ* e = this; e; e = e->globals) {
|
||||
if (Decl* d = e->decls->findDecl(s)) {
|
||||
@@ -43,7 +44,7 @@ Decl* Environ::findDecl(const string& s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
Decl* Environ::findFunc(const string& s)
|
||||
Decl* Environ::findFunc(const std::string& s)
|
||||
{
|
||||
for (Environ* e = this; e; e = e->globals) {
|
||||
if (Decl* d = e->funcDecls->findDecl(s))
|
||||
@@ -52,7 +53,7 @@ Decl* Environ::findFunc(const string& s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
Type* Environ::findType(const string& s)
|
||||
Type* Environ::findType(const std::string& s)
|
||||
{
|
||||
if (s == "%")
|
||||
return Type::int_type;
|
||||
@@ -67,7 +68,7 @@ Type* Environ::findType(const string& s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
Label* Environ::findLabel(const string& s)
|
||||
Label* Environ::findLabel(const std::string& s)
|
||||
{
|
||||
for (int k = 0; k < labels.size(); ++k)
|
||||
if (labels[k]->name == s)
|
||||
@@ -75,16 +76,16 @@ Label* Environ::findLabel(const string& s)
|
||||
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);
|
||||
labels.push_back(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;
|
||||
return t;
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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 "std.hpp"
|
||||
#include <stdutil.hpp>
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
ExprNode::ExprNode() : sem_type(0) {}
|
||||
|
||||
ExprNode::ExprNode(Type* t) : sem_type(t) {}
|
||||
|
||||
//////////////////////////////////
|
||||
// Cast an expression to a type //
|
||||
@@ -19,6 +26,13 @@ ExprNode* ExprNode::castTo(Type* ty, Environ* e)
|
||||
return cast;
|
||||
}
|
||||
|
||||
CastNode::CastNode(ExprNode* ex, Type* ty) : expr(ex), type(ty) {}
|
||||
|
||||
CastNode::~CastNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
|
||||
ExprNode* CastNode::semant(Environ* e)
|
||||
{
|
||||
if (!expr->sem_type) {
|
||||
@@ -81,6 +95,18 @@ TNode* CastNode::translate(Codegen* g)
|
||||
/////////////////////////////
|
||||
// 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)
|
||||
{
|
||||
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 //
|
||||
///////////////////
|
||||
@@ -203,6 +236,13 @@ TNode* CallNode::translate(Codegen* g)
|
||||
return t;
|
||||
}
|
||||
|
||||
VarExprNode::VarExprNode(VarNode* v) : var(v) {}
|
||||
|
||||
VarExprNode::~VarExprNode()
|
||||
{
|
||||
delete var;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// Variable expression //
|
||||
/////////////////////////
|
||||
@@ -246,7 +286,7 @@ float IntConstNode::floatValue()
|
||||
return value;
|
||||
}
|
||||
|
||||
string IntConstNode::stringValue()
|
||||
std::string IntConstNode::stringValue()
|
||||
{
|
||||
return itoa(value);
|
||||
}
|
||||
@@ -284,7 +324,7 @@ float FloatConstNode::floatValue()
|
||||
return value;
|
||||
}
|
||||
|
||||
string FloatConstNode::stringValue()
|
||||
std::string FloatConstNode::stringValue()
|
||||
{
|
||||
return ftoa(value);
|
||||
}
|
||||
@@ -292,14 +332,14 @@ string FloatConstNode::stringValue()
|
||||
/////////////////////
|
||||
// String constant //
|
||||
/////////////////////
|
||||
StringConstNode::StringConstNode(const string& s) : value(s)
|
||||
StringConstNode::StringConstNode(const std::string& s) : value(s)
|
||||
{
|
||||
sem_type = Type::string_type;
|
||||
}
|
||||
|
||||
TNode* StringConstNode::translate(Codegen* g)
|
||||
{
|
||||
string lab = genLabel();
|
||||
std::string lab = genLabel();
|
||||
g->s_data(value, lab);
|
||||
return call("__bbStrConst", global(lab));
|
||||
}
|
||||
@@ -314,11 +354,18 @@ float StringConstNode::floatValue()
|
||||
return (float)atof(value);
|
||||
}
|
||||
|
||||
string StringConstNode::stringValue()
|
||||
std::string StringConstNode::stringValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
UniExprNode::UniExprNode(int op, ExprNode* expr) : op(op), expr(expr) {}
|
||||
|
||||
UniExprNode::~UniExprNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// Unary operator //
|
||||
////////////////////
|
||||
@@ -399,6 +446,14 @@ TNode* UniExprNode::translate(Codegen* g)
|
||||
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 //
|
||||
/////////////////////////////////////////////////////
|
||||
@@ -466,6 +521,14 @@ TNode* BinExprNode::translate(Codegen* g)
|
||||
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 //
|
||||
///////////////////////////
|
||||
@@ -594,6 +657,14 @@ TNode* ArithExprNode::translate(Codegen* g)
|
||||
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 //
|
||||
/////////////////////////
|
||||
@@ -695,6 +766,8 @@ TNode* RelExprNode::translate(Codegen* g)
|
||||
return compare(op, l, r, opType);
|
||||
}
|
||||
|
||||
NewNode::NewNode(const std::string& i) : ident(i) {}
|
||||
|
||||
////////////////////
|
||||
// New expression //
|
||||
////////////////////
|
||||
@@ -713,6 +786,8 @@ TNode* NewNode::translate(Codegen* g)
|
||||
return call("__bbObjNew", global("_t" + ident));
|
||||
}
|
||||
|
||||
FirstNode::FirstNode(const std::string& i) : ident(i) {}
|
||||
|
||||
////////////////////
|
||||
// First of class //
|
||||
////////////////////
|
||||
@@ -729,6 +804,8 @@ TNode* FirstNode::translate(Codegen* g)
|
||||
return call("__bbObjFirst", global("_t" + ident));
|
||||
}
|
||||
|
||||
LastNode::LastNode(const std::string& i) : ident(i) {}
|
||||
|
||||
///////////////////
|
||||
// Last of class //
|
||||
///////////////////
|
||||
@@ -745,6 +822,13 @@ TNode* LastNode::translate(Codegen* g)
|
||||
return call("__bbObjLast", global("_t" + ident));
|
||||
}
|
||||
|
||||
AfterNode::AfterNode(ExprNode* e) : expr(e) {}
|
||||
|
||||
AfterNode::~AfterNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// Next of object //
|
||||
////////////////////
|
||||
@@ -767,6 +851,13 @@ TNode* AfterNode::translate(Codegen* g)
|
||||
return call("__bbObjNext", t);
|
||||
}
|
||||
|
||||
BeforeNode::BeforeNode(ExprNode* e) : expr(e) {}
|
||||
|
||||
BeforeNode::~BeforeNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// Prev of object //
|
||||
////////////////////
|
||||
@@ -803,6 +894,13 @@ TNode* NullNode::translate(Codegen* g)
|
||||
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 //
|
||||
/////////////////
|
||||
@@ -825,6 +923,13 @@ TNode* ObjectCastNode::translate(Codegen* g)
|
||||
return t;
|
||||
}
|
||||
|
||||
ObjectHandleNode::ObjectHandleNode(ExprNode* e) : expr(e) {}
|
||||
|
||||
ObjectHandleNode::~ObjectHandleNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// Object Handle //
|
||||
///////////////////
|
||||
@@ -842,3 +947,13 @@ TNode* ObjectHandleNode::translate(Codegen* g)
|
||||
TNode* t = expr->translate(g);
|
||||
return call("__bbObjToHandle", t);
|
||||
}
|
||||
|
||||
ExprNode* ConstNode::semant(Environ* e)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
ConstNode* ConstNode::constNode()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
@@ -1,15 +1,24 @@
|
||||
|
||||
#ifndef EXPRNODE_H
|
||||
#define EXPRNODE_H
|
||||
|
||||
#pragma once
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "node.hpp"
|
||||
#include "type.hpp"
|
||||
|
||||
class Codegen;
|
||||
class Environ;
|
||||
struct DeclSeq;
|
||||
struct Decl;
|
||||
struct ConstNode; //is constant int,float or string
|
||||
struct VarNode;
|
||||
|
||||
struct ExprNode : public Node {
|
||||
Type* sem_type;
|
||||
ExprNode() : sem_type(0) {}
|
||||
ExprNode(Type* t) : sem_type(t) {}
|
||||
class ExprNode : public Node {
|
||||
std::shared_ptr<Type> sem_type;
|
||||
|
||||
|
||||
public:
|
||||
ExprNode();
|
||||
ExprNode(std::shared_ptr<Type> t);
|
||||
|
||||
ExprNode* castTo(Type* ty, Environ* e);
|
||||
ExprNode* semant(Environ* e, Type* ty);
|
||||
@@ -22,77 +31,58 @@ struct ExprNode : public Node {
|
||||
}
|
||||
};
|
||||
|
||||
struct ExprSeqNode : public Node {
|
||||
vector<ExprNode*> exprs;
|
||||
~ExprSeqNode()
|
||||
{
|
||||
for (; exprs.size(); exprs.pop_back())
|
||||
delete exprs.back();
|
||||
}
|
||||
void push_back(ExprNode* e)
|
||||
{
|
||||
exprs.push_back(e);
|
||||
}
|
||||
int size()
|
||||
{
|
||||
return exprs.size();
|
||||
}
|
||||
class ExprSeqNode : public Node {
|
||||
std::list<std::shared_ptr<ExprNode>> exprs;
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
#include "varnode.hpp"
|
||||
|
||||
struct CastNode : public ExprNode {
|
||||
ExprNode* expr;
|
||||
Type* type;
|
||||
CastNode(ExprNode* ex, Type* ty) : expr(ex), type(ty) {}
|
||||
~CastNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
CastNode(ExprNode* ex, Type* ty);
|
||||
~CastNode();
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
struct CallNode : public ExprNode {
|
||||
string ident, tag;
|
||||
std::string ident, tag;
|
||||
ExprSeqNode* exprs;
|
||||
Decl* sem_decl;
|
||||
CallNode(const string& i, const string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {}
|
||||
~CallNode()
|
||||
{
|
||||
delete exprs;
|
||||
}
|
||||
CallNode(const std::string& i, const std::string& t, ExprSeqNode* e);
|
||||
~CallNode();
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
struct VarExprNode : public ExprNode {
|
||||
VarNode* var;
|
||||
VarExprNode(VarNode* v) : var(v) {}
|
||||
~VarExprNode()
|
||||
{
|
||||
delete var;
|
||||
}
|
||||
VarExprNode(VarNode* v);
|
||||
~VarExprNode();
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
struct ConstNode : public ExprNode {
|
||||
ExprNode* semant(Environ* e)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
ConstNode* constNode()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
ExprNode* semant(Environ* e);
|
||||
ConstNode* constNode();
|
||||
virtual int intValue() = 0;
|
||||
virtual float floatValue() = 0;
|
||||
virtual string stringValue() = 0;
|
||||
virtual std::string stringValue() = 0;
|
||||
};
|
||||
|
||||
struct IntConstNode : public ConstNode {
|
||||
@@ -101,7 +91,7 @@ struct IntConstNode : public ConstNode {
|
||||
TNode* translate(Codegen* g);
|
||||
int intValue();
|
||||
float floatValue();
|
||||
string stringValue();
|
||||
std::string stringValue();
|
||||
};
|
||||
|
||||
struct FloatConstNode : public ConstNode {
|
||||
@@ -110,26 +100,23 @@ struct FloatConstNode : public ConstNode {
|
||||
TNode* translate(Codegen* g);
|
||||
int intValue();
|
||||
float floatValue();
|
||||
string stringValue();
|
||||
std::string stringValue();
|
||||
};
|
||||
|
||||
struct StringConstNode : public ConstNode {
|
||||
string value;
|
||||
StringConstNode(const string& s);
|
||||
std::string value;
|
||||
StringConstNode(const std::string& s);
|
||||
TNode* translate(Codegen* g);
|
||||
int intValue();
|
||||
float floatValue();
|
||||
string stringValue();
|
||||
std::string stringValue();
|
||||
};
|
||||
|
||||
struct UniExprNode : public ExprNode {
|
||||
int op;
|
||||
ExprNode* expr;
|
||||
UniExprNode(int op, ExprNode* expr) : op(op), expr(expr) {}
|
||||
~UniExprNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
UniExprNode(int op, ExprNode* expr);
|
||||
~UniExprNode();
|
||||
ExprNode* constize();
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
@@ -139,12 +126,8 @@ struct UniExprNode : public ExprNode {
|
||||
struct BinExprNode : public ExprNode {
|
||||
int op;
|
||||
ExprNode *lhs, *rhs;
|
||||
BinExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {}
|
||||
~BinExprNode()
|
||||
{
|
||||
delete lhs;
|
||||
delete rhs;
|
||||
}
|
||||
BinExprNode(int op, ExprNode* lhs, ExprNode* rhs);
|
||||
~BinExprNode();
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
@@ -153,12 +136,8 @@ struct BinExprNode : public ExprNode {
|
||||
struct ArithExprNode : public ExprNode {
|
||||
int op;
|
||||
ExprNode *lhs, *rhs;
|
||||
ArithExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {}
|
||||
~ArithExprNode()
|
||||
{
|
||||
delete lhs;
|
||||
delete rhs;
|
||||
}
|
||||
ArithExprNode(int op, ExprNode* lhs, ExprNode* rhs);
|
||||
~ArithExprNode();
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
@@ -168,55 +147,45 @@ struct RelExprNode : public ExprNode {
|
||||
int op;
|
||||
ExprNode *lhs, *rhs;
|
||||
Type* opType;
|
||||
RelExprNode(int op, ExprNode* lhs, ExprNode* rhs) : op(op), lhs(lhs), rhs(rhs) {}
|
||||
~RelExprNode()
|
||||
{
|
||||
delete lhs;
|
||||
delete rhs;
|
||||
}
|
||||
RelExprNode(int op, ExprNode* lhs, ExprNode* rhs);
|
||||
~RelExprNode();
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
struct NewNode : public ExprNode {
|
||||
string ident;
|
||||
NewNode(const string& i) : ident(i) {}
|
||||
std::string ident;
|
||||
NewNode(const std::string& i);
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
struct FirstNode : public ExprNode {
|
||||
string ident;
|
||||
FirstNode(const string& i) : ident(i) {}
|
||||
std::string ident;
|
||||
FirstNode(const std::string& i);
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
struct LastNode : public ExprNode {
|
||||
string ident;
|
||||
LastNode(const string& i) : ident(i) {}
|
||||
std::string ident;
|
||||
LastNode(const std::string& i);
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
struct AfterNode : public ExprNode {
|
||||
ExprNode* expr;
|
||||
AfterNode(ExprNode* e) : expr(e) {}
|
||||
~AfterNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
AfterNode(ExprNode* e);
|
||||
~AfterNode();
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
struct BeforeNode : public ExprNode {
|
||||
ExprNode* expr;
|
||||
BeforeNode(ExprNode* e) : expr(e) {}
|
||||
~BeforeNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
BeforeNode(ExprNode* e);
|
||||
~BeforeNode();
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
@@ -228,25 +197,17 @@ struct NullNode : public ExprNode {
|
||||
|
||||
struct ObjectCastNode : public ExprNode {
|
||||
ExprNode* expr;
|
||||
string type_ident;
|
||||
ObjectCastNode(ExprNode* e, const string& t) : expr(e), type_ident(t) {}
|
||||
~ObjectCastNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
std::string type_ident;
|
||||
ObjectCastNode(ExprNode* e, const std::string& t);
|
||||
~ObjectCastNode();
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
struct ObjectHandleNode : public ExprNode {
|
||||
ExprNode* expr;
|
||||
ObjectHandleNode(ExprNode* e) : expr(e) {}
|
||||
~ObjectHandleNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
ObjectHandleNode(ExprNode* e);
|
||||
~ObjectHandleNode();
|
||||
ExprNode* semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -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) {}
|
||||
};
|
||||
@@ -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 "std.hpp"
|
||||
#include "varnode.hpp"
|
||||
#include "exprnode.hpp"
|
||||
|
||||
set<string> Node::usedfuncs;
|
||||
#include <stdutil.hpp>
|
||||
|
||||
std::set<std::string> Node::usedfuncs;
|
||||
|
||||
///////////////////////////////
|
||||
// generic exception thrower //
|
||||
@@ -12,19 +21,19 @@ void Node::ex()
|
||||
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,7 +41,7 @@ void Node::ex(const string& e, int pos, const string& f)
|
||||
///////////////////////////////
|
||||
VarNode* Node::genLocal(Environ* e, Type* ty)
|
||||
{
|
||||
string t = genLabel();
|
||||
std::string t = genLabel();
|
||||
Decl* d = e->decls->insertDecl(t, ty, DECL_LOCAL);
|
||||
return new DeclVarNode(d);
|
||||
}
|
||||
@@ -121,7 +130,7 @@ TNode* Node::deleteVars(Environ* e)
|
||||
for (int k = 0; k < e->decls->size(); ++k) {
|
||||
Decl* d = e->decls->decls[k];
|
||||
Type* type = d->type;
|
||||
string func;
|
||||
std::string func;
|
||||
if (type == Type::string_type) {
|
||||
if (d->kind == DECL_LOCAL || d->kind == DECL_PARAM) {
|
||||
func = "__bbStrRelease";
|
||||
@@ -212,7 +221,7 @@ TNode* Node::compare(int op, TNode* l, TNode* r, Type* ty)
|
||||
/////////////////////////////////
|
||||
// calculate the type of a tag //
|
||||
/////////////////////////////////
|
||||
Type* Node::tagType(const string& tag, Environ* e)
|
||||
Type* Node::tagType(const std::string& tag, Environ* e)
|
||||
{
|
||||
Type* t;
|
||||
if (tag.size()) {
|
||||
@@ -227,7 +236,7 @@ Type* Node::tagType(const string& tag, Environ* e)
|
||||
////////////////////////////////
|
||||
// Generate a fresh ASM label //
|
||||
////////////////////////////////
|
||||
string Node::genLabel()
|
||||
std::string Node::genLabel()
|
||||
{
|
||||
static int cnt;
|
||||
return "_" + itoa(++cnt & 0x7fffffff);
|
||||
@@ -236,7 +245,7 @@ string Node::genLabel()
|
||||
//////////////////////////////////////////////////////
|
||||
// create a stmt-type function call with int result //
|
||||
//////////////////////////////////////////////////////
|
||||
TNode* Node::call(const string& func, TNode* a0, TNode* a1, TNode* a2)
|
||||
TNode* Node::call(const std::string& func, TNode* a0, TNode* a1, TNode* a2)
|
||||
{
|
||||
int size = 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 //
|
||||
////////////////////////////////////////////////////////
|
||||
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;
|
||||
TNode* t = 0;
|
||||
@@ -289,7 +298,7 @@ TNode* Node::move(TNode* src, TNode* 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);
|
||||
}
|
||||
@@ -329,27 +338,27 @@ TNode* Node::ret()
|
||||
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);
|
||||
}
|
||||
|
||||
TNode* Node::jump(const string& s)
|
||||
TNode* Node::jump(const std::string& 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -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 @@
|
||||
|
||||
#ifndef NODES_H
|
||||
#define NODES_H
|
||||
|
||||
#pragma once
|
||||
#include "declnode.hpp"
|
||||
#include "exprnode.hpp"
|
||||
#include "prognode.hpp"
|
||||
#include "stmtnode.hpp"
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,14 @@
|
||||
|
||||
#include "parser.hpp"
|
||||
#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;
|
||||
#endif
|
||||
|
||||
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) {}
|
||||
|
||||
ProgNode* Parser::parse(const string& main)
|
||||
std::shared_ptr<ProgNode> Parser::parse(const std::string& main)
|
||||
{
|
||||
incfile = main;
|
||||
|
||||
consts = new DeclSeqNode();
|
||||
structs = new DeclSeqNode();
|
||||
funcs = new DeclSeqNode();
|
||||
datas = new DeclSeqNode();
|
||||
StmtSeqNode* stmts = 0;
|
||||
consts = std::make_shared<DeclSeqNode>();
|
||||
structs = std::make_shared<DeclSeqNode>();
|
||||
funcs = std::make_shared<DeclSeqNode>();
|
||||
datas = std::make_shared<DeclSeqNode>();
|
||||
|
||||
std::shared_ptr<StmtSeqNode> stmts;
|
||||
|
||||
try {
|
||||
stmts = parseStmtSeq(STMTS_PROG);
|
||||
if (toker->curr() != EOF)
|
||||
if (toker->curr() != EOF) {
|
||||
exp("end-of-file");
|
||||
} catch (Ex) {
|
||||
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()) {
|
||||
case NEXT:
|
||||
@@ -75,11 +69,11 @@ void Parser::exp(const string& s)
|
||||
ex("Expecting " + s);
|
||||
}
|
||||
|
||||
string Parser::parseIdent()
|
||||
std::string Parser::parseIdent()
|
||||
{
|
||||
if (toker->curr() != IDENT)
|
||||
exp("identifier");
|
||||
string t = toker->text();
|
||||
std::string t = toker->text();
|
||||
toker->next();
|
||||
return t;
|
||||
}
|
||||
@@ -87,36 +81,32 @@ string Parser::parseIdent()
|
||||
void Parser::parseChar(int c)
|
||||
{
|
||||
if (toker->curr() != c)
|
||||
exp(string("'") + char(c) + string("'"));
|
||||
exp(std::string("'") + char(c) + std::string("'"));
|
||||
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);
|
||||
return stmts.release();
|
||||
return stmts;
|
||||
}
|
||||
|
||||
void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
|
||||
void Parser::parseStmtSeq(std::shared_ptr<StmtSeqNode> stmts, int scope)
|
||||
{
|
||||
for (;;) {
|
||||
while (toker->curr() == ':' || (scope != STMTS_LINE && toker->curr() == '\n'))
|
||||
while (toker->curr() == ':' || (scope != STMTS_LINE && toker->curr() == '\n')) {
|
||||
toker->next();
|
||||
}
|
||||
StmtNode* result = 0;
|
||||
|
||||
int pos = toker->pos();
|
||||
|
||||
#ifdef DEMO
|
||||
if (Toker::chars_toked > TEXTLIMIT) {
|
||||
ex("Demo version source limit exceeded");
|
||||
}
|
||||
#endif
|
||||
switch (toker->curr()) {
|
||||
case INCLUDE: {
|
||||
if (toker->next() != STRINGCONST)
|
||||
exp("include filename");
|
||||
string inc = toker->text();
|
||||
std::string inc = toker->text();
|
||||
toker->next();
|
||||
inc = inc.substr(1, inc.size() - 2);
|
||||
|
||||
@@ -129,32 +119,31 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
|
||||
if (included.find(inc) != included.end())
|
||||
break;
|
||||
|
||||
ifstream i_stream(inc.c_str());
|
||||
std::ifstream i_stream(inc.c_str());
|
||||
if (!i_stream.good())
|
||||
ex("Unable to open include file");
|
||||
|
||||
Toker i_toker(i_stream);
|
||||
std::swap(this->incfile, inc);
|
||||
|
||||
string t_inc = incfile;
|
||||
incfile = inc;
|
||||
Toker* t_toker = toker;
|
||||
toker = &i_toker;
|
||||
std::shared_ptr<Toker> i_toker = std::make_shared<Toker>(i_stream);
|
||||
std::swap(this->toker, i_toker);
|
||||
|
||||
included.insert(incfile);
|
||||
|
||||
a_ptr<StmtSeqNode> ss(parseStmtSeq(scope));
|
||||
if (toker->curr() != EOF)
|
||||
std::shared_ptr<StmtSeqNode> ss = parseStmtSeq(scope);
|
||||
if (toker->curr() != EOF) {
|
||||
exp("end-of-file");
|
||||
}
|
||||
|
||||
result = new IncludeNode(incfile, ss.release());
|
||||
result = new IncludeNode(incfile, ss);
|
||||
|
||||
toker = t_toker;
|
||||
incfile = t_inc;
|
||||
std::swap(this->toker, i_toker);
|
||||
std::swap(this->incfile, inc);
|
||||
} break;
|
||||
case IDENT: {
|
||||
string ident = toker->text();
|
||||
std::string ident = toker->text();
|
||||
toker->next();
|
||||
string tag = parseTypeTag();
|
||||
std::string tag = parseTypeTag();
|
||||
if (arrayDecls.find(ident) == arrayDecls.end() && toker->curr() != '=' && toker->curr() != '\\'
|
||||
&& toker->curr() != '[') {
|
||||
//must be a function
|
||||
@@ -201,13 +190,13 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
|
||||
} break;
|
||||
case WHILE: {
|
||||
toker->next();
|
||||
a_ptr<ExprNode> expr(parseExpr(false));
|
||||
a_ptr<StmtSeqNode> stmts(parseStmtSeq(STMTS_BLOCK));
|
||||
std::shared_ptr<ExprNode> expr = parseExpr(false);
|
||||
std::shared_ptr<StmtSeqNode> stmts = parseStmtSeq(STMTS_BLOCK);
|
||||
int pos = toker->pos();
|
||||
if (toker->curr() != WEND)
|
||||
exp("'Wend'");
|
||||
toker->next();
|
||||
result = new WhileNode(expr.release(), stmts.release(), pos);
|
||||
result = new WhileNode(expr, stmts, pos);
|
||||
} break;
|
||||
case REPEAT: {
|
||||
toker->next();
|
||||
@@ -261,7 +250,7 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
|
||||
exp("variable assignment");
|
||||
if (toker->next() == EACH) {
|
||||
toker->next();
|
||||
string ident = parseIdent();
|
||||
std::string ident = parseIdent();
|
||||
stmts = parseStmtSeq(STMTS_BLOCK);
|
||||
int pos = toker->pos();
|
||||
if (toker->curr() != NEXT)
|
||||
@@ -295,12 +284,12 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
|
||||
} break;
|
||||
case GOTO: {
|
||||
toker->next();
|
||||
string t = parseIdent();
|
||||
std::string t = parseIdent();
|
||||
result = new GotoNode(t);
|
||||
} break;
|
||||
case GOSUB: {
|
||||
toker->next();
|
||||
string t = parseIdent();
|
||||
std::string t = parseIdent();
|
||||
result = new GosubNode(t);
|
||||
} break;
|
||||
case RETURN: {
|
||||
@@ -310,7 +299,7 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
|
||||
case BBDELETE: {
|
||||
if (toker->next() == EACH) {
|
||||
toker->next();
|
||||
string t = parseIdent();
|
||||
std::string t = parseIdent();
|
||||
result = new DeleteEachNode(t);
|
||||
} else {
|
||||
ExprNode* expr = parseExpr(false);
|
||||
@@ -406,7 +395,7 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
|
||||
break;
|
||||
case '.': {
|
||||
toker->next();
|
||||
string t = parseIdent();
|
||||
std::string t = parseIdent();
|
||||
result = new LabelNode(t, datas->size());
|
||||
} break;
|
||||
default:
|
||||
@@ -420,7 +409,7 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope)
|
||||
}
|
||||
}
|
||||
|
||||
string Parser::parseTypeTag()
|
||||
std::string Parser::parseTypeTag()
|
||||
{
|
||||
switch (toker->curr()) {
|
||||
case '%':
|
||||
@@ -439,14 +428,14 @@ string Parser::parseTypeTag()
|
||||
return "";
|
||||
}
|
||||
|
||||
VarNode* Parser::parseVar()
|
||||
std::shared_ptr<VarNode> Parser::parseVar()
|
||||
{
|
||||
string ident = parseIdent();
|
||||
string tag = parseTypeTag();
|
||||
std::string ident = parseIdent();
|
||||
std::string tag = parseTypeTag();
|
||||
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;
|
||||
if (toker->curr() == '(') {
|
||||
@@ -462,8 +451,8 @@ VarNode* Parser::parseVar(const string& ident, const string& tag)
|
||||
for (;;) {
|
||||
if (toker->curr() == '\\') {
|
||||
toker->next();
|
||||
string ident = parseIdent();
|
||||
string tag = parseTypeTag();
|
||||
std::string ident = parseIdent();
|
||||
std::string tag = parseTypeTag();
|
||||
ExprNode* expr = new VarExprNode(var.release());
|
||||
var = new FieldVarNode(expr, ident, tag);
|
||||
} else if (toker->curr() == '[') {
|
||||
@@ -481,11 +470,11 @@ VarNode* Parser::parseVar(const string& ident, const string& tag)
|
||||
return var.release();
|
||||
}
|
||||
|
||||
DeclNode* Parser::parseVarDecl(int kind, bool constant)
|
||||
std::shared_ptr<DeclNode> Parser::parseVarDecl(int kind, bool constant)
|
||||
{
|
||||
int pos = toker->pos();
|
||||
string ident = parseIdent();
|
||||
string tag = parseTypeTag();
|
||||
std::string ident = parseIdent();
|
||||
std::string tag = parseTypeTag();
|
||||
DeclNode* d;
|
||||
if (toker->curr() == '[') {
|
||||
if (constant)
|
||||
@@ -510,11 +499,11 @@ DeclNode* Parser::parseVarDecl(int kind, bool constant)
|
||||
return d;
|
||||
}
|
||||
|
||||
DimNode* Parser::parseArrayDecl()
|
||||
std::shared_ptr<DimNode> Parser::parseArrayDecl()
|
||||
{
|
||||
int pos = toker->pos();
|
||||
string ident = parseIdent();
|
||||
string tag = parseTypeTag();
|
||||
std::string ident = parseIdent();
|
||||
std::string tag = parseTypeTag();
|
||||
if (toker->curr() != '(')
|
||||
exp("'('");
|
||||
toker->next();
|
||||
@@ -530,11 +519,11 @@ DimNode* Parser::parseArrayDecl()
|
||||
return d;
|
||||
}
|
||||
|
||||
DeclNode* Parser::parseFuncDecl()
|
||||
std::shared_ptr<DeclNode> Parser::parseFuncDecl()
|
||||
{
|
||||
int pos = toker->pos();
|
||||
string ident = parseIdent();
|
||||
string tag = parseTypeTag();
|
||||
std::string ident = parseIdent();
|
||||
std::string tag = parseTypeTag();
|
||||
if (toker->curr() != '(')
|
||||
exp("'('");
|
||||
a_ptr<DeclSeqNode> params(new DeclSeqNode());
|
||||
@@ -562,10 +551,10 @@ DeclNode* Parser::parseFuncDecl()
|
||||
return d;
|
||||
}
|
||||
|
||||
DeclNode* Parser::parseStructDecl()
|
||||
std::shared_ptr<DeclNode> Parser::parseStructDecl()
|
||||
{
|
||||
int pos = toker->pos();
|
||||
string ident = parseIdent();
|
||||
std::string ident = parseIdent();
|
||||
while (toker->curr() == '\n')
|
||||
toker->next();
|
||||
a_ptr<DeclSeqNode> fields(new DeclSeqNode());
|
||||
@@ -586,7 +575,7 @@ DeclNode* Parser::parseStructDecl()
|
||||
return d;
|
||||
}
|
||||
|
||||
IfNode* Parser::parseIf()
|
||||
std::shared_ptr<IfNode> Parser::parseIf()
|
||||
{
|
||||
a_ptr<ExprNode> expr;
|
||||
a_ptr<StmtSeqNode> stmts, elseOpt;
|
||||
@@ -618,124 +607,145 @@ IfNode* Parser::parseIf()
|
||||
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;
|
||||
while (ExprNode* e = parseExpr(opt)) {
|
||||
while (std::shared_ptr<ExprNode> e = parseExpr(opt)) {
|
||||
exprs->push_back(e);
|
||||
if (toker->curr() != ',')
|
||||
break;
|
||||
toker->next();
|
||||
opt = false;
|
||||
}
|
||||
return exprs.release();
|
||||
return exprs;
|
||||
}
|
||||
|
||||
ExprNode* Parser::parseExpr(bool opt)
|
||||
std::shared_ptr<ExprNode> Parser::parseExpr(bool opt)
|
||||
{
|
||||
if (toker->curr() == NOT) {
|
||||
toker->next();
|
||||
ExprNode* expr = parseExpr1(false);
|
||||
return new RelExprNode('=', expr, new IntConstNode(0));
|
||||
std::shared_ptr<ExprNode> expr = parseExpr1(false);
|
||||
return std::make_shared<RelExprNode>('=', expr, std::make_shared<IntConstNode>(0));
|
||||
}
|
||||
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)
|
||||
return 0;
|
||||
for (;;) {
|
||||
int c = toker->curr();
|
||||
if (c != AND && c != OR && c != XOR)
|
||||
return lhs.release();
|
||||
if (c != AND && c != OR && c != XOR) {
|
||||
return lhs;
|
||||
}
|
||||
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)
|
||||
return 0;
|
||||
for (;;) {
|
||||
int c = toker->curr();
|
||||
if (c != '<' && c != '>' && c != '=' && c != LE && c != GE && c != NE)
|
||||
return lhs.release();
|
||||
if (c != '<' && c != '>' && c != '=' && c != LE && c != GE && c != NE) {
|
||||
return lhs;
|
||||
}
|
||||
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)
|
||||
return 0;
|
||||
for (;;) {
|
||||
int c = toker->curr();
|
||||
if (c != '+' && c != '-')
|
||||
return lhs.release();
|
||||
if (c != '+' && c != '-') {
|
||||
return lhs;
|
||||
}
|
||||
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)
|
||||
return 0;
|
||||
for (;;) {
|
||||
int c = toker->curr();
|
||||
if (c != SHL && c != SHR && c != SAR)
|
||||
return lhs.release();
|
||||
if (c != SHL && c != SHR && c != SAR) {
|
||||
return lhs;
|
||||
}
|
||||
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));
|
||||
if (!lhs)
|
||||
std::shared_ptr<ExprNode> rhs;
|
||||
std::shared_ptr<ExprNode> lhs = parseExpr6(opt);
|
||||
if (!lhs) {
|
||||
return 0;
|
||||
}
|
||||
for (;;) {
|
||||
int c = toker->curr();
|
||||
if (c != '*' && c != '/' && c != MOD)
|
||||
return lhs.release();
|
||||
if (c != '*' && c != '/' && c != MOD) {
|
||||
return lhs;
|
||||
}
|
||||
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));
|
||||
if (!lhs)
|
||||
return 0;
|
||||
std::shared_ptr<ExprNode> rhs;
|
||||
std::shared_ptr<ExprNode> lhs = parseUniExpr(opt);
|
||||
if (!lhs) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int c = toker->curr();
|
||||
if (c != '^')
|
||||
return lhs.release();
|
||||
if (c != '^') {
|
||||
return lhs;
|
||||
}
|
||||
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;
|
||||
string t;
|
||||
std::shared_ptr<ExprNode> result;
|
||||
std::string t;
|
||||
|
||||
int c = toker->curr();
|
||||
switch (c) {
|
||||
@@ -798,10 +808,10 @@ ExprNode* Parser::parseUniExpr(bool opt)
|
||||
return result;
|
||||
}
|
||||
|
||||
ExprNode* Parser::parsePrimary(bool opt)
|
||||
std::shared_ptr<ExprNode> Parser::parsePrimary(bool opt)
|
||||
{
|
||||
a_ptr<ExprNode> expr;
|
||||
string t, ident, tag;
|
||||
std::string t, ident, tag;
|
||||
ExprNode* result = 0;
|
||||
int n, k;
|
||||
|
||||
@@ -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 "std.hpp"
|
||||
#include <stdutil.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! //
|
||||
//////////////////
|
||||
Environ* ProgNode::semant(Environ* e)
|
||||
std::shared_ptr<Environ> ProgNode::semant(Environ* e)
|
||||
{
|
||||
file_lab = genLabel();
|
||||
|
||||
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);
|
||||
structs->proto(env->typeDecls, env);
|
||||
@@ -22,11 +43,11 @@ Environ* ProgNode::semant(Environ* e)
|
||||
datas->proto(env->decls, env);
|
||||
datas->semant(env);
|
||||
|
||||
sem_env = env.release();
|
||||
return sem_env;
|
||||
sem_env = env;
|
||||
return env;
|
||||
}
|
||||
|
||||
void ProgNode::translate(Codegen* g, const vector<UserFunc>& usrfuncs)
|
||||
void ProgNode::translate(Codegen* g, const std::vector<UserFunc>& usrfuncs)
|
||||
{
|
||||
int k;
|
||||
|
||||
@@ -55,7 +76,7 @@ void ProgNode::translate(Codegen* g, const vector<UserFunc>& usrfuncs)
|
||||
if (t)
|
||||
g->code(t);
|
||||
if (g->debug) {
|
||||
string t = genLabel();
|
||||
std::string t = genLabel();
|
||||
g->s_data("<main program>", 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);
|
||||
|
||||
//library functions
|
||||
map<string, vector<int>> libFuncs;
|
||||
std::map<std::string, std::vector<int>> libFuncs;
|
||||
|
||||
//lib ptrs
|
||||
g->flush();
|
||||
@@ -111,12 +132,12 @@ void ProgNode::translate(Codegen* g, const vector<UserFunc>& usrfuncs)
|
||||
//LIBS chunk
|
||||
g->flush();
|
||||
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) {
|
||||
//lib name
|
||||
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) {
|
||||
const UserFunc& fn = usrfuncs[fns[j]];
|
||||
@@ -140,3 +161,8 @@ void ProgNode::translate(Codegen* g, const vector<UserFunc>& usrfuncs)
|
||||
//Thats IT!
|
||||
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)
|
||||
{}
|
||||
@@ -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"
|
||||
#include "std.hpp"
|
||||
static std::string fileLabel;
|
||||
static std::map<std::string, std::string> fileMap;
|
||||
|
||||
static string fileLabel;
|
||||
static map<string, string> fileMap;
|
||||
StmtNode::StmtNode() : pos(-1) {}
|
||||
|
||||
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 = "";
|
||||
fileMap.clear();
|
||||
@@ -21,6 +33,14 @@ void StmtSeqNode::reset(const string& file, const string& 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 //
|
||||
////////////////////////
|
||||
@@ -29,7 +49,7 @@ void StmtSeqNode::semant(Environ* e)
|
||||
for (int k = 0; k < stmts.size(); ++k) {
|
||||
try {
|
||||
stmts[k]->semant(e);
|
||||
} catch (Ex& x) {
|
||||
} catch (BlitzException& x) {
|
||||
if (x.pos < 0)
|
||||
x.pos = stmts[k]->pos;
|
||||
if (!x.file.size())
|
||||
@@ -41,14 +61,14 @@ void StmtSeqNode::semant(Environ* e)
|
||||
|
||||
void StmtSeqNode::translate(Codegen* g)
|
||||
{
|
||||
string t = fileLabel;
|
||||
std::string t = fileLabel;
|
||||
fileLabel = file.size() ? fileMap[file] : "";
|
||||
for (int k = 0; k < stmts.size(); ++k) {
|
||||
StmtNode* stmt = stmts[k];
|
||||
stmt->debug(stmts[k]->pos, g);
|
||||
try {
|
||||
stmt->translate(g);
|
||||
} catch (Ex& x) {
|
||||
} catch (BlitzException& x) {
|
||||
if (x.pos < 0)
|
||||
x.pos = stmts[k]->pos;
|
||||
if (!x.file.size())
|
||||
@@ -59,9 +79,21 @@ void StmtSeqNode::translate(Codegen* g)
|
||||
fileLabel = t;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// An Include! //
|
||||
/////////////////
|
||||
void StmtSeqNode::push_back(StmtNode* s)
|
||||
{
|
||||
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)
|
||||
{
|
||||
label = genLabel();
|
||||
@@ -78,9 +110,17 @@ void IncludeNode::translate(Codegen* g)
|
||||
stmts->translate(g);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// a declaration //
|
||||
///////////////////
|
||||
// Declare Statement
|
||||
DeclStmtNode::DeclStmtNode(DeclNode* d) : decl(d)
|
||||
{
|
||||
pos = d->pos;
|
||||
}
|
||||
|
||||
DeclStmtNode::~DeclStmtNode()
|
||||
{
|
||||
delete decl;
|
||||
}
|
||||
|
||||
void DeclStmtNode::semant(Environ* e)
|
||||
{
|
||||
decl->proto(e->decls, e);
|
||||
@@ -92,15 +132,20 @@ void DeclStmtNode::translate(Codegen* g)
|
||||
decl->translate(g);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Dim AND declare an Array //
|
||||
//////////////////////////////
|
||||
// Dim Array Statement
|
||||
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)
|
||||
{
|
||||
Type* t = tagType(tag, e);
|
||||
if (Decl* d = e->findDecl(ident)) {
|
||||
ArrayType* a = d->type->arrayType();
|
||||
if (!a || a->dims != exprs->size() || (t && a->elementType != t)) {
|
||||
if (!a || a->size != exprs->size() || (t && a->type != t)) {
|
||||
ex("Duplicate identifier");
|
||||
}
|
||||
sem_type = a;
|
||||
@@ -133,7 +178,7 @@ void DimNode::translate(Codegen* g)
|
||||
return;
|
||||
|
||||
int et, k;
|
||||
Type* ty = sem_type->arrayType()->elementType;
|
||||
Type* ty = sem_type->arrayType()->type;
|
||||
if (ty == Type::int_type)
|
||||
et = 1;
|
||||
else if (ty == Type::float_type)
|
||||
@@ -151,6 +196,14 @@ void DimNode::translate(Codegen* g)
|
||||
g->i_data(0);
|
||||
}
|
||||
|
||||
AssNode::AssNode(VarNode* var, ExprNode* expr) : var(var), expr(expr) {}
|
||||
|
||||
AssNode::~AssNode()
|
||||
{
|
||||
delete var;
|
||||
delete expr;
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Assignment //
|
||||
////////////////
|
||||
@@ -170,6 +223,13 @@ void AssNode::translate(Codegen* g)
|
||||
g->code(var->store(g, expr->translate(g)));
|
||||
}
|
||||
|
||||
ExprStmtNode::ExprStmtNode(ExprNode* e) : expr(e) {}
|
||||
|
||||
ExprStmtNode::~ExprStmtNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// Expression statement //
|
||||
//////////////////////////
|
||||
@@ -186,6 +246,8 @@ void ExprStmtNode::translate(Codegen* g)
|
||||
g->code(t);
|
||||
}
|
||||
|
||||
LabelNode::LabelNode(const std::string& s, int sz) : ident(s), data_sz(sz) {}
|
||||
|
||||
////////////////
|
||||
// user label //
|
||||
////////////////
|
||||
@@ -206,6 +268,8 @@ void LabelNode::translate(Codegen* g)
|
||||
g->label("_l" + ident);
|
||||
}
|
||||
|
||||
RestoreNode::RestoreNode(const std::string& i) : ident(i) {}
|
||||
|
||||
//////////////////
|
||||
// Restore data //
|
||||
//////////////////
|
||||
@@ -231,6 +295,8 @@ void RestoreNode::translate(Codegen* g)
|
||||
g->code(call("__bbRestore", t));
|
||||
}
|
||||
|
||||
GotoNode::GotoNode(const std::string& s) : ident(s) {}
|
||||
|
||||
////////////////////
|
||||
// Goto statement //
|
||||
////////////////////
|
||||
@@ -247,6 +313,8 @@ void GotoNode::translate(Codegen* g)
|
||||
g->code(jump("_l" + ident));
|
||||
}
|
||||
|
||||
GosubNode::GosubNode(const std::string& s) : ident(s) {}
|
||||
|
||||
/////////////////////
|
||||
// Gosub statement //
|
||||
/////////////////////
|
||||
@@ -264,6 +332,15 @@ void GosubNode::translate(Codegen* g)
|
||||
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 //
|
||||
//////////////////
|
||||
@@ -284,11 +361,11 @@ void IfNode::translate(Codegen* g)
|
||||
else if (elseOpt)
|
||||
elseOpt->translate(g);
|
||||
} else {
|
||||
string _else = genLabel();
|
||||
std::string _else = genLabel();
|
||||
g->code(jumpf(expr->translate(g), _else));
|
||||
stmts->translate(g);
|
||||
if (elseOpt) {
|
||||
string _else2 = genLabel();
|
||||
std::string _else2 = genLabel();
|
||||
g->code(jump(_else2));
|
||||
g->label(_else);
|
||||
elseOpt->translate(g);
|
||||
@@ -313,6 +390,14 @@ void ExitNode::translate(Codegen* g)
|
||||
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 //
|
||||
/////////////////////
|
||||
@@ -320,14 +405,14 @@ void WhileNode::semant(Environ* e)
|
||||
{
|
||||
expr = expr->semant(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);
|
||||
e->setBreak(brk);
|
||||
}
|
||||
|
||||
void WhileNode::translate(Codegen* g)
|
||||
{
|
||||
string loop = genLabel();
|
||||
std::string loop = genLabel();
|
||||
if (ConstNode* c = expr->constNode()) {
|
||||
if (!c->intValue())
|
||||
return;
|
||||
@@ -335,7 +420,7 @@ void WhileNode::translate(Codegen* g)
|
||||
stmts->translate(g);
|
||||
g->code(jump(loop));
|
||||
} else {
|
||||
string cond = genLabel();
|
||||
std::string cond = genLabel();
|
||||
g->code(jump(cond));
|
||||
g->label(loop);
|
||||
stmts->translate(g);
|
||||
@@ -381,7 +466,7 @@ void ForNode::semant(Environ* e)
|
||||
if (!stepExpr->constNode())
|
||||
ex("Step value must be constant");
|
||||
|
||||
string brk = e->setBreak(sem_brk = genLabel());
|
||||
std::string brk = e->setBreak(sem_brk = genLabel());
|
||||
stmts->semant(e);
|
||||
e->setBreak(brk);
|
||||
}
|
||||
@@ -394,8 +479,8 @@ void ForNode::translate(Codegen* g)
|
||||
//initial assignment
|
||||
g->code(var->store(g, fromExpr->translate(g)));
|
||||
|
||||
string cond = genLabel();
|
||||
string loop = genLabel();
|
||||
std::string cond = genLabel();
|
||||
std::string loop = genLabel();
|
||||
g->code(jump(cond));
|
||||
g->label(loop);
|
||||
stmts->translate(g);
|
||||
@@ -415,6 +500,16 @@ void ForNode::translate(Codegen* g)
|
||||
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 //
|
||||
///////////////////////////////
|
||||
@@ -431,17 +526,17 @@ void ForEachNode::semant(Environ* e)
|
||||
if (t != ty)
|
||||
ex("Type mismatch");
|
||||
|
||||
string brk = e->setBreak(sem_brk = genLabel());
|
||||
std::string brk = e->setBreak(sem_brk = genLabel());
|
||||
stmts->semant(e);
|
||||
e->setBreak(brk);
|
||||
}
|
||||
|
||||
void ForEachNode::translate(Codegen* g)
|
||||
{
|
||||
TNode *t, *l, *r;
|
||||
string _loop = genLabel();
|
||||
TNode * t, *l, *r;
|
||||
std::string _loop = genLabel();
|
||||
|
||||
string objFirst, objNext;
|
||||
std::string objFirst, objNext;
|
||||
|
||||
if (var->isObjParam()) {
|
||||
objFirst = "__bbObjEachFirst2";
|
||||
@@ -466,6 +561,13 @@ void ForEachNode::translate(Codegen* g)
|
||||
g->label(sem_brk);
|
||||
}
|
||||
|
||||
ReturnNode::ReturnNode(ExprNode* e) : expr(e) {}
|
||||
|
||||
ReturnNode::~ReturnNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// 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 //
|
||||
//////////////////////
|
||||
@@ -524,6 +633,8 @@ void DeleteNode::translate(Codegen* g)
|
||||
g->code(call("__bbObjDelete", t));
|
||||
}
|
||||
|
||||
DeleteEachNode::DeleteEachNode(const std::string& t) : typeIdent(t) {}
|
||||
|
||||
///////////////////////////
|
||||
// Delete each of a type //
|
||||
///////////////////////////
|
||||
@@ -539,6 +650,14 @@ void DeleteEachNode::translate(Codegen* g)
|
||||
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 //
|
||||
///////////////////////////
|
||||
@@ -562,10 +681,26 @@ void InsertNode::translate(Codegen* g)
|
||||
TNode* t2 = expr2->translate(g);
|
||||
if (g->debug)
|
||||
t2 = jumpf(t2, "__bbNullObjEx");
|
||||
string s = before ? "__bbObjInsBefore" : "__bbObjInsAfter";
|
||||
std::string s = before ? "__bbObjInsBefore" : "__bbObjInsAfter";
|
||||
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 //
|
||||
////////////////////////
|
||||
@@ -597,8 +732,8 @@ void SelectNode::translate(Codegen* g)
|
||||
|
||||
g->code(sem_temp->store(g, expr->translate(g)));
|
||||
|
||||
vector<string> labs;
|
||||
string brk = genLabel();
|
||||
std::vector<std::string> labs;
|
||||
std::string brk = genLabel();
|
||||
|
||||
for (k = 0; k < cases.size(); ++k) {
|
||||
CaseNode* c = cases[k];
|
||||
@@ -622,13 +757,21 @@ void SelectNode::translate(Codegen* g)
|
||||
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 //
|
||||
////////////////////////////
|
||||
void RepeatNode::semant(Environ* e)
|
||||
{
|
||||
sem_brk = genLabel();
|
||||
string brk = e->setBreak(sem_brk);
|
||||
std::string brk = e->setBreak(sem_brk);
|
||||
stmts->semant(e);
|
||||
e->setBreak(brk);
|
||||
if (expr) {
|
||||
@@ -639,7 +782,7 @@ void RepeatNode::semant(Environ* e)
|
||||
|
||||
void RepeatNode::translate(Codegen* g)
|
||||
{
|
||||
string loop = genLabel();
|
||||
std::string loop = genLabel();
|
||||
g->label(loop);
|
||||
stmts->translate(g);
|
||||
debug(untilPos, g);
|
||||
@@ -656,6 +799,13 @@ void RepeatNode::translate(Codegen* g)
|
||||
g->label(sem_brk);
|
||||
}
|
||||
|
||||
ReadNode::ReadNode(VarNode* v) : var(v) {}
|
||||
|
||||
ReadNode::~ReadNode()
|
||||
{
|
||||
delete var;
|
||||
}
|
||||
|
||||
///////////////
|
||||
// Read data //
|
||||
///////////////
|
||||
@@ -679,3 +829,11 @@ void ReadNode::translate(Codegen* g)
|
||||
t = call("__bbReadStr");
|
||||
g->code(var->store(g, t));
|
||||
}
|
||||
|
||||
CaseNode::CaseNode(ExprSeqNode* e, StmtSeqNode* s) : exprs(e), stmts(s) {}
|
||||
|
||||
CaseNode::~CaseNode()
|
||||
{
|
||||
delete exprs;
|
||||
delete stmts;
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
#include "toker.hpp"
|
||||
#include <cctype>
|
||||
#include "ex.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
#include <stdutil.hpp>
|
||||
|
||||
int Toker::chars_toked;
|
||||
|
||||
static map<string, int> alphaTokes, lowerTokes;
|
||||
static std::map<std::string, int> alphaTokes, lowerTokes;
|
||||
|
||||
static void makeKeywords()
|
||||
{
|
||||
@@ -81,20 +81,20 @@ static void makeKeywords()
|
||||
alphaTokes["Shr"] = SHR;
|
||||
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) {
|
||||
lowerTokes[tolower(it->first)] = it->second;
|
||||
}
|
||||
made = true;
|
||||
}
|
||||
|
||||
Toker::Toker(istream& in) : in(in), curr_row(-1)
|
||||
Toker::Toker(std::istream& in) : in(in), curr_row(-1)
|
||||
{
|
||||
makeKeywords();
|
||||
nextline();
|
||||
}
|
||||
|
||||
map<string, int>& Toker::getKeywords()
|
||||
std::map<std::string, int>& Toker::getKeywords()
|
||||
{
|
||||
makeKeywords();
|
||||
return alphaTokes;
|
||||
@@ -110,7 +110,7 @@ int Toker::curr()
|
||||
return tokes[curr_toke].n;
|
||||
}
|
||||
|
||||
string Toker::text()
|
||||
std::string Toker::text()
|
||||
{
|
||||
int from = tokes[curr_toke].from, to = tokes[curr_toke].to;
|
||||
return line.substr(from, to - from);
|
||||
@@ -186,20 +186,20 @@ void Toker::nextline()
|
||||
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])) {
|
||||
int t = k;
|
||||
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()) {
|
||||
k = t;
|
||||
ident = s;
|
||||
}
|
||||
}
|
||||
|
||||
map<string, int>::iterator it = lowerTokes.find(ident);
|
||||
std::map<std::string, int>::iterator it = lowerTokes.find(ident);
|
||||
|
||||
if (it == lowerTokes.end()) {
|
||||
for (int n = from; n < k; ++n)
|
||||
@@ -1,12 +1,13 @@
|
||||
|
||||
/*
|
||||
|
||||
The Toker converts an inout stream into tokens for use by the parser.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TOKER_H
|
||||
#define TOKER_H
|
||||
#pragma once
|
||||
#include <istream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum {
|
||||
DIM = 0x8000,
|
||||
@@ -86,28 +87,26 @@ enum {
|
||||
|
||||
class Toker {
|
||||
public:
|
||||
Toker(istream& in);
|
||||
Toker(std::istream& in);
|
||||
|
||||
int pos();
|
||||
int curr();
|
||||
int next();
|
||||
string text();
|
||||
std::string text();
|
||||
int lookAhead(int n);
|
||||
|
||||
static int chars_toked;
|
||||
|
||||
static map<string, int>& getKeywords();
|
||||
static std::map<std::string, int>& getKeywords();
|
||||
|
||||
private:
|
||||
struct Toke {
|
||||
int n, from, to;
|
||||
Toke(int n, int f, int t) : n(n), from(f), to(t) {}
|
||||
};
|
||||
istream& in;
|
||||
string line;
|
||||
vector<Toke> tokes;
|
||||
std::istream& in;
|
||||
std::string line;
|
||||
std::vector<Toke> tokes;
|
||||
void nextline();
|
||||
int curr_row, curr_toke;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -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");
|
||||
@@ -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,6 +1,4 @@
|
||||
|
||||
#ifndef VAR_H
|
||||
#define VAR_H
|
||||
#pragma once
|
||||
|
||||
struct Type;
|
||||
|
||||
@@ -10,5 +8,3 @@ struct Var {
|
||||
|
||||
Var(int i, Type* t) : index(i), type(t) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
|
||||
#include "nodes.hpp"
|
||||
#include "std.hpp"
|
||||
#include "varnode.hpp"
|
||||
#include "codegen.hpp"
|
||||
#include "environ.hpp"
|
||||
#include "exprnode.hpp"
|
||||
#include "type.hpp"
|
||||
|
||||
//////////////////////////////////
|
||||
// Common get/set for variables //
|
||||
@@ -28,6 +30,12 @@ bool VarNode::isObjParam()
|
||||
return false;
|
||||
}
|
||||
|
||||
DeclVarNode::DeclVarNode(Decl* d) : sem_decl(d)
|
||||
{
|
||||
if (d)
|
||||
sem_type = d->type;
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// Declared var //
|
||||
//////////////////
|
||||
@@ -54,6 +62,8 @@ bool DeclVarNode::isObjParam()
|
||||
return sem_type->structType() && sem_decl->kind == DECL_PARAM;
|
||||
}
|
||||
|
||||
IdentVarNode::IdentVarNode(const std::string& i, const std::string& t) : ident(i), tag(t) {}
|
||||
|
||||
///////////////
|
||||
// Ident var //
|
||||
///////////////
|
||||
@@ -92,11 +102,11 @@ void ArrayVarNode::semant(Environ* e)
|
||||
if (!sem_decl || !(sem_decl->kind & DECL_ARRAY))
|
||||
ex("Array not found");
|
||||
ArrayType* a = sem_decl->type->arrayType();
|
||||
if (t && t != a->elementType)
|
||||
if (t && t != a->type)
|
||||
ex("array type mismtach");
|
||||
if (a->dims != exprs->size())
|
||||
if (a->size != exprs->size())
|
||||
ex("incorrect number of dimensions");
|
||||
sem_type = a->elementType;
|
||||
sem_type = a->type;
|
||||
}
|
||||
|
||||
TNode* ArrayVarNode::translate(Codegen* g)
|
||||
@@ -144,6 +154,14 @@ TNode* FieldVarNode::translate(Codegen* g)
|
||||
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 //
|
||||
////////////////
|
||||
@@ -188,3 +206,17 @@ TNode* VectorVarNode::translate(Codegen* 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
|
||||
#define VARNODE_H
|
||||
|
||||
#include "varnode.hpp"
|
||||
class Environ;
|
||||
class Codegen;
|
||||
struct TNode;
|
||||
struct ExprNode;
|
||||
struct ExprSeqNode;
|
||||
|
||||
struct VarNode : public Node {
|
||||
Type* sem_type;
|
||||
@@ -17,15 +22,9 @@ struct VarNode : public Node {
|
||||
virtual TNode* translate(Codegen* g) = 0;
|
||||
};
|
||||
|
||||
#include "decl.hpp"
|
||||
|
||||
struct DeclVarNode : public VarNode {
|
||||
Decl* sem_decl;
|
||||
DeclVarNode(Decl* d = 0) : sem_decl(d)
|
||||
{
|
||||
if (d)
|
||||
sem_type = d->type;
|
||||
}
|
||||
DeclVarNode(Decl* d = 0);
|
||||
void semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
virtual TNode* store(Codegen* g, TNode* n);
|
||||
@@ -33,33 +32,27 @@ struct DeclVarNode : public VarNode {
|
||||
};
|
||||
|
||||
struct IdentVarNode : public DeclVarNode {
|
||||
string ident, tag;
|
||||
IdentVarNode(const string& i, const string& t) : ident(i), tag(t) {}
|
||||
std::string ident, tag;
|
||||
IdentVarNode(const std::string& i, const std::string& t);
|
||||
void semant(Environ* e);
|
||||
};
|
||||
|
||||
struct ArrayVarNode : public VarNode {
|
||||
string ident, tag;
|
||||
std::string ident, tag;
|
||||
ExprSeqNode* exprs;
|
||||
Decl* sem_decl;
|
||||
ArrayVarNode(const string& i, const string& t, ExprSeqNode* e) : ident(i), tag(t), exprs(e) {}
|
||||
~ArrayVarNode()
|
||||
{
|
||||
delete exprs;
|
||||
}
|
||||
ArrayVarNode(const std::string& i, const std::string& t, ExprSeqNode* e);
|
||||
~ArrayVarNode();
|
||||
void semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
struct FieldVarNode : public VarNode {
|
||||
ExprNode* expr;
|
||||
string ident, tag;
|
||||
std::string ident, tag;
|
||||
Decl* sem_field;
|
||||
FieldVarNode(ExprNode* e, const string& i, const string& t) : expr(e), ident(i), tag(t) {}
|
||||
~FieldVarNode()
|
||||
{
|
||||
delete expr;
|
||||
}
|
||||
FieldVarNode(ExprNode* e, const std::string& i, const std::string& t);
|
||||
~FieldVarNode();
|
||||
void semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
@@ -68,14 +61,8 @@ struct VectorVarNode : public VarNode {
|
||||
ExprNode* expr;
|
||||
ExprSeqNode* exprs;
|
||||
VectorType* vec_type;
|
||||
VectorVarNode(ExprNode* e, ExprSeqNode* es) : expr(e), exprs(es) {}
|
||||
~VectorVarNode()
|
||||
{
|
||||
delete expr;
|
||||
delete exprs;
|
||||
}
|
||||
VectorVarNode(ExprNode* e, ExprSeqNode* es);
|
||||
~VectorVarNode();
|
||||
void semant(Environ* e);
|
||||
TNode* translate(Codegen* g);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 );
|
||||
};
|
||||
@@ -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;
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user