diff --git a/compiler/CMakeLists.txt b/compiler/CMakeLists.txt index bd4c386..c6f15cd 100644 --- a/compiler/CMakeLists.txt +++ b/compiler/CMakeLists.txt @@ -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 $ ${fmod_BINARIES} ${FreeImage_BINARIES} + DESTINATION bin + OPTIONAL + ) +endif() diff --git a/compiler/assem.hpp b/compiler/assem.hpp deleted file mode 100644 index 42e7029..0000000 --- a/compiler/assem.hpp +++ /dev/null @@ -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 \ No newline at end of file diff --git a/compiler/assem_x86/asm_insts.cpp b/compiler/assem_x86/asm_insts.cpp deleted file mode 100644 index 805ee6d..0000000 --- a/compiler/assem_x86/asm_insts.cpp +++ /dev/null @@ -1,2878 +0,0 @@ -// -//This is generated code - do not modify!!!!! -// - -#include "..\std.h" - -#include "insts.h" - -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}; diff --git a/compiler/assem_x86/assem_x86.h b/compiler/assem_x86/assem_x86.h deleted file mode 100644 index bf2925d..0000000 --- a/compiler/assem_x86/assem_x86.h +++ /dev/null @@ -1,37 +0,0 @@ - -#ifndef ASSEM_X86_H -#define ASSEM_X86_H - -#include "../assem.h" - -#include -#include -#include - -#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 diff --git a/compiler/assem_x86/operand.h b/compiler/assem_x86/operand.h deleted file mode 100644 index 7c3eba7..0000000 --- a/compiler/assem_x86/operand.h +++ /dev/null @@ -1,32 +0,0 @@ - -#ifndef OPERAND_H -#define OPERAND_H - -#include -#include - -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 diff --git a/compiler/block.h_old b/compiler/block.h_old deleted file mode 100644 index d6d66ec..0000000 --- a/compiler/block.h_old +++ /dev/null @@ -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 children; - - vector code; - vector data; -}; - -#endif \ No newline at end of file diff --git a/compiler/codegen_x86/codegen_x86.h b/compiler/codegen_x86/codegen_x86.h deleted file mode 100644 index 425913c..0000000 --- a/compiler/codegen_x86/codegen_x86.h +++ /dev/null @@ -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 ); -}; \ No newline at end of file diff --git a/compiler/codegen_x86/tile.h b/compiler/codegen_x86/tile.h deleted file mode 100644 index c26264d..0000000 --- a/compiler/codegen_x86/tile.h +++ /dev/null @@ -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 diff --git a/compiler/compiler.cpp b/compiler/compiler.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/compiler/compiler.hpp b/compiler/compiler.hpp deleted file mode 100644 index e69de29..0000000 diff --git a/compiler/decl.hpp b/compiler/decl.hpp deleted file mode 100644 index 330823d..0000000 --- a/compiler/decl.hpp +++ /dev/null @@ -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 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 diff --git a/compiler/decl.old b/compiler/decl.old deleted file mode 100644 index 57c27df..0000000 --- a/compiler/decl.old +++ /dev/null @@ -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 diff --git a/compiler/declnode.hpp b/compiler/declnode.hpp deleted file mode 100644 index 2153e30..0000000 --- a/compiler/declnode.hpp +++ /dev/null @@ -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 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 diff --git a/compiler/environ.hpp b/compiler/environ.hpp deleted file mode 100644 index 62f8114..0000000 --- a/compiler/environ.hpp +++ /dev/null @@ -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 types; - - vector labels; - Environ* globals; - Type* returnType; - string funcLabel, breakLabel; - list 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 diff --git a/compiler/ex.hpp b/compiler/ex.hpp deleted file mode 100644 index a89ad93..0000000 --- a/compiler/ex.hpp +++ /dev/null @@ -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 \ No newline at end of file diff --git a/compiler/gen/CMakeLists.txt b/compiler/gen/CMakeLists.txt new file mode 100644 index 0000000..4480ce5 --- /dev/null +++ b/compiler/gen/CMakeLists.txt @@ -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" + "$/nasm_insts.txt" +) diff --git a/compiler/gen/insts.cpp b/compiler/gen/insts.cpp new file mode 100644 index 0000000..dd85fd4 --- /dev/null +++ b/compiler/gen/insts.cpp @@ -0,0 +1,1946 @@ +// +//This is generated code - do not modify!!!!! +// + +#include "../insts.h" + +const Inst* insts = {"aaa", + 0, + 0, + 0, + "\x37", + "aas", + 0, + 0, + 0, + "\x3F", + "aad", + 0, + 0, + 0, + "\xD5\x0A", + "0", + IMM, + 0, + IB, + "\xD5", + "aam", + 0, + 0, + 0, + "\xD4\x0A", + "0", + IMM, + 0, + IB, + "\xD4", + "adc", + R_M8, + REG8, + _R, + "\x10", + "0", + R_M16, + REG16, + O16 | _R, + "\x11", + "0", + REG8, + R_M8, + _R, + "\x12", + "0", + REG16, + R_M16, + O16 | _R, + "\x13", + "0", + R_M8, + IMM8, + _2 | IB, + "\x80", + "0", + R_M16, + IMM16, + O16 | _2 | IW, + "\x81", + "0", + R_M16, + IMM8, + O16 | _2 | IB, + "\x83", + "0", + AL, + IMM8, + IB, + "\x14", + "0", + AX, + IMM16, + O16 | IW, + "\x15", + "add", + R_M8, + REG8, + _R, + "\x00", + "0", + R_M16, + REG16, + O16 | _R, + "\x01", + "0", + REG8, + R_M8, + _R, + "\x02", + "0", + REG16, + R_M16, + O16 | _R, + "\x03", + "0", + R_M8, + IMM8, + _0 | IB, + "\x80", + "0", + R_M16, + IMM16, + O16 | _0 | IW, + "\x81", + "0", + R_M16, + IMM8, + O16 | _0 | IB, + "\x83", + "0", + AL, + IMM8, + IB, + "\x04", + "0", + AX, + IMM16, + O16 | IW, + "\x05", + "and", + R_M8, + REG8, + _R, + "\x20", + "0", + R_M16, + REG16, + O16 | _R, + "\x21", + "0", + REG8, + R_M8, + _R, + "\x22", + "0", + REG16, + R_M16, + O16 | _R, + "\x23", + "0", + R_M8, + IMM8, + _4 | IB, + "\x80", + "0", + R_M16, + IMM16, + O16 | _4 | IW, + "\x81", + "0", + R_M16, + IMM8, + O16 | _4 | IB, + "\x83", + "0", + AL, + IMM8, + IB, + "\x24", + "0", + AX, + IMM16, + O16 | IW, + "\x25", + "arpl", + R_M16, + REG16, + _R, + "\x63", + "bound", + REG16, + MEM, + O16 | _R, + "\x62", + "bsf", + REG16, + R_M16, + O16 | _R, + "\x0F\xBC", + "bsr", + REG16, + R_M16, + O16 | _R, + "\x0F\xBD", + "bt", + R_M16, + REG16, + O16 | _R, + "\x0F\xA3", + "0", + R_M16, + IMM8, + O16 | _4 | IB, + "\x0F\xBA", + "btc", + R_M16, + REG16, + O16 | _R, + "\x0F\xBB", + "0", + R_M16, + IMM8, + O16 | _7 | IB, + "\x0F\xBA", + "btr", + R_M16, + REG16, + O16 | _R, + "\x0F\xB3", + "0", + R_M16, + IMM8, + O16 | _6 | IB, + "\x0F\xBA", + "bts", + R_M16, + REG16, + O16 | _R, + "\x0F\xAB", + "0", + R_M16, + IMM, + O16 | _5 | IB, + "\x0F\xBA", + "call", + IMM, + 0, + 0, + "\xE8", + "0", + R_M16, + 0, + O16 | _2, + "\xFF", + "cbw", + 0, + 0, + O16, + "\x98", + "cwd", + 0, + 0, + O16, + "\x99", + "clc", + 0, + 0, + 0, + "\xF8", + "cld", + 0, + 0, + 0, + "\xFC", + "cli", + 0, + 0, + 0, + "\xFA", + "clts", + 0, + 0, + 0, + "\x0F\x06", + "cmc", + 0, + 0, + 0, + "\xF5", + "cmovcc", + REG16, + R_M16, + O16 | PLUSCC | _R, + "\x0F\x40", + "cmp", + R_M8, + REG8, + _R, + "\x38", + "0", + R_M16, + REG16, + O16 | _R, + "\x39", + "0", + REG8, + R_M8, + _R, + "\x3A", + "0", + REG16, + R_M16, + O16 | _R, + "\x3B", + "0", + R_M8, + IMM8, + _0 | IB, + "\x80", + "0", + R_M16, + IMM16, + O16 | _0 | IW, + "\x81", + "0", + R_M16, + IMM8, + O16 | _0 | IB, + "\x83", + "0", + AL, + IMM8, + IB, + "\x3C", + "0", + AX, + IMM16, + O16 | IW, + "\x3D", + "cmpsb", + 0, + 0, + 0, + "\xA6", + "cmpsw", + 0, + 0, + O16, + "\xA7", + "cmpxchg", + R_M8, + REG8, + _R, + "\x0F\xB0", + "0", + R_M16, + REG16, + O16 | _R, + "\x0F\xB1", + "cmpxchg486", + R_M8, + REG8, + _R, + "\x0F\xA6", + "0", + R_M16, + REG16, + O16 | _R, + "\x0F\xA7", + "cmpxchg8b", + MEM, + 0, + _1, + "\x0F\xC7", + "cpuid", + 0, + 0, + 0, + "\x0F\xA2", + "daa", + 0, + 0, + 0, + "\x27", + "das", + 0, + 0, + 0, + "\x2F", + "dec", + REG16, + 0, + O16 | PLUSREG, + "\x48", + "0", + R_M8, + 0, + _1, + "\xFE", + "0", + R_M16, + 0, + O16 | _1, + "\xFF", + "div", + R_M8, + 0, + _6, + "\xF6", + "0", + R_M16, + 0, + O16 | _6, + "\xF7", + "emms", + 0, + 0, + 0, + "\x0F\x77", + "enter", + IMM, + IMM, + IW | IB, + "\xC8", + "f2xm1", + 0, + 0, + 0, + "\xD9\xF0", + "fabs", + 0, + 0, + 0, + "\xD9\xE1", + "fadd", + MEM32, + 0, + _0, + "\xD8", + "fchs", + 0, + 0, + 0, + "\xD9\xE0", + "fclex", + 0, + 0, + 0, + "\x9B\xDB\xE2", + "fnclex", + 0, + 0, + 0, + "\xDB\xE2", + "fcom", + MEM32, + 0, + _2, + "\xD8", + "fcomp", + MEM32, + 0, + _3, + "\xD8", + "fcompp", + 0, + 0, + 0, + "\xDE\xD9", + "fcos", + 0, + 0, + 0, + "\xD9\xFF", + "fdecstp", + 0, + 0, + 0, + "\xD9\xF6", + "fdisi", + 0, + 0, + 0, + "\x9B\xDB\xE1", + "fndisi", + 0, + 0, + 0, + "\xDB\xE1", + "feni", + 0, + 0, + 0, + "\x9B\xDB\xE0", + "fneni", + 0, + 0, + 0, + "\xDB\xE0", + "fdiv", + MEM32, + 0, + _6, + "\xD8", + "fdivr", + MEM32, + 0, + _0, + "\xD8", + "fiadd", + MEM16, + 0, + _0, + "\xDE", + "0", + MEM32, + 0, + _0, + "\xDA", + "ficom", + MEM16, + 0, + _2, + "\xDE", + "0", + MEM32, + 0, + _2, + "\xDA", + "ficomp", + MEM16, + 0, + _3, + "\xDE", + "0", + MEM32, + 0, + _3, + "\xDA", + "fidiv", + MEM16, + 0, + _6, + "\xDE", + "0", + MEM32, + 0, + _6, + "\xDA", + "fidivr", + MEM16, + 0, + _0, + "\xDE", + "0", + MEM32, + 0, + _0, + "\xDA", + "fild", + MEM16, + 0, + _0, + "\xDF", + "0", + MEM32, + 0, + _0, + "\xDB", + "fist", + MEM16, + 0, + _2, + "\xDF", + "0", + MEM32, + 0, + _2, + "\xDB", + "fistp", + MEM16, + 0, + _3, + "\xDF", + "0", + MEM32, + 0, + _3, + "\xDB", + "fimul", + MEM16, + 0, + _1, + "\xDE", + "0", + MEM32, + 0, + _1, + "\xDA", + "fincstp", + 0, + 0, + 0, + "\xD9\xF7", + "finit", + 0, + 0, + 0, + "\x9B\xDB\xE3", + "fninit", + 0, + 0, + 0, + "\xDB\xE3", + "fisub", + MEM16, + 0, + _4, + "\xDE", + "0", + MEM32, + 0, + _4, + "\xDA", + "fisubr", + MEM16, + 0, + _5, + "\xDE", + "0", + MEM32, + 0, + _5, + "\xDA", + "fld", + MEM32, + 0, + _0, + "\xD9", + "fld1", + 0, + 0, + 0, + "\xD9\xE8", + "fldl2e", + 0, + 0, + 0, + "\xD9\xEA", + "fldl2t", + 0, + 0, + 0, + "\xD9\xE9", + "fldlg2", + 0, + 0, + 0, + "\xD9\xEC", + "fldln2", + 0, + 0, + 0, + "\xD9\xED", + "fldpi", + 0, + 0, + 0, + "\xD9\xEB", + "fldz", + 0, + 0, + 0, + "\xD9\xEE", + "fldcw", + MEM16, + 0, + _5, + "\xD9", + "fldenv", + MEM, + 0, + _4, + "\xD9", + "fmul", + MEM32, + 0, + _1, + "\xD8", + "fnop", + 0, + 0, + 0, + "\xD9\xD0", + "fpatan", + 0, + 0, + 0, + "\xD9\xF3", + "fptan", + 0, + 0, + 0, + "\xD9\xF2", + "fprem", + 0, + 0, + 0, + "\xD9\xF8", + "fprem1", + 0, + 0, + 0, + "\xD9\xF5", + "frndint", + 0, + 0, + 0, + "\xD9\xFC", + "fsave", + MEM, + 0, + _6, + "\x9B\xDD", + "fnsave", + MEM, + 0, + _6, + "\xDD", + "frstor", + MEM, + 0, + _4, + "\xDD", + "fscale", + 0, + 0, + 0, + "\xD9\xFD", + "fsetpm", + 0, + 0, + 0, + "\xDB\xE4", + "fsin", + 0, + 0, + 0, + "\xD9\xFE", + "fsincos", + 0, + 0, + 0, + "\xD9\xFB", + "fsqrt", + 0, + 0, + 0, + "\xD9\xFA", + "fst", + MEM32, + 0, + _2, + "\xD9", + "fstp", + MEM32, + 0, + _3, + "\xD9", + "fstcw", + MEM16, + 0, + _0, + "\x9B\xD9", + "fnstcw", + MEM16, + 0, + _0, + "\xD9", + "fstenv", + MEM, + 0, + _6, + "\x9B\xD9", + "fnstenv", + MEM, + 0, + _6, + "\xD9", + "fstsw", + MEM16, + 0, + _0, + "\x9B\xDD", + "0", + AX, + 0, + 0, + "\x9B\xDF\xE0", + "fnstsw", + MEM16, + 0, + _0, + "\xDD", + "0", + AX, + 0, + 0, + "\xDF\xE0", + "fsub", + MEM32, + 0, + _4, + "\xD8", + "fsubr", + MEM32, + 0, + _5, + "\xD8", + "ftst", + 0, + 0, + 0, + "\xD9\xE4", + "fucompp", + 0, + 0, + 0, + "\xDA\xE9", + "fxam", + 0, + 0, + 0, + "\xD9\xE5", + "fxch", + 0, + 0, + 0, + "\xD9\xC9", + "fxtract", + 0, + 0, + 0, + "\xD9\xF4", + "fyl2x", + 0, + 0, + 0, + "\xD9\xF1", + "fyl2xp1", + 0, + 0, + 0, + "\xD9\xF9", + "hlt", + 0, + 0, + 0, + "\xF4", + "ibts", + R_M16, + REG16, + O16 | _R, + "\x0F\xA7", + "idiv", + R_M8, + 0, + _7, + "\xF6", + "0", + R_M16, + 0, + O16 | _7, + "\xF7", + "imul", + R_M8, + 0, + _5, + "\xF6", + "0", + R_M16, + 0, + O16 | _5, + "\xF7", + "0", + REG16, + R_M16, + O16 | _R, + "\x0F\xAF", + "0", + REG16, + IMM8, + O16 | _R | IB, + "\x6B", + "0", + REG16, + IMM16, + O16 | _R | IW, + "\x69", + "in", + AL, + IMM8, + IB, + "\xE4", + "0", + AX, + IMM8, + O16 | IB, + "\xE5", + "inc", + REG16, + 0, + O16 | PLUSREG, + "\x40", + "0", + R_M8, + 0, + _0, + "\xFE", + "0", + R_M16, + 0, + O16 | _0, + "\xFF", + "insb", + 0, + 0, + 0, + "\x6C", + "insw", + 0, + 0, + O16, + "\x6D", + "int", + IMM8, + 0, + IB, + "\xCD", + "int1", + 0, + 0, + 0, + "\xF1", + "icebp", + 0, + 0, + 0, + "\xF1", + "int01", + 0, + 0, + 0, + "\xF1", + "int3", + 0, + 0, + 0, + "\xCC", + "into", + 0, + 0, + 0, + "\xCE", + "invd", + 0, + 0, + 0, + "\x0F\x08", + "invlpg", + MEM, + 0, + _0, + "\x0F\x01", + "iret", + 0, + 0, + 0, + "\xCF", + "iretw", + 0, + 0, + O16, + "\xCF", + "jcxz", + IMM, + 0, + O16, + "\xE3", + "jmp", + IMM, + 0, + 0, + "\xE9", + "0", + R_M16, + 0, + O16 | _4, + "\xFF", + "jcc", + IMM, + 0, + PLUSCC, + "\x70", + "lahf", + 0, + 0, + 0, + "\x9F", + "lar", + REG16, + R_M16, + O16 | _R, + "\x0F\x02", + "lds", + REG16, + MEM, + O16 | _R, + "\xC5", + "les", + REG16, + MEM, + O16 | _R, + "\xC4", + "lfs", + REG16, + MEM, + O16 | _R, + "\x0F\xB4", + "lgs", + REG16, + MEM, + O16 | _R, + "\x0F\xB5", + "lss", + REG16, + MEM, + O16 | _R, + "\x0F\xB2", + "lea", + REG16, + MEM, + O16 | _R, + "\x8D", + "leave", + 0, + 0, + 0, + "\xC9", + "lgdt", + MEM, + 0, + _2, + "\x0F\x01", + "lidt", + MEM, + 0, + _3, + "\x0F\x01", + "lldt", + R_M16, + 0, + _2, + "\x0F\x00", + "lmsw", + R_M16, + 0, + _6, + "\x0F\x01", + "loadall", + 0, + 0, + 0, + "\x0F\x07", + "loadall286", + 0, + 0, + 0, + "\x0F\x05", + "lodsb", + 0, + 0, + 0, + "\xAC", + "lodsw", + 0, + 0, + O16, + "\xAD", + "loop", + IMM, + 0, + 0, + "\xE2", + "0", + IMM, + CX, + 0, + "\xa1\xE2", + "0", + IMM, + ECX, + 0, + "\xa3\xE2", + "loope", + IMM, + 0, + 0, + "\xE1", + "0", + IMM, + CX, + 0, + "\xa1\xE1", + "0", + IMM, + ECX, + 0, + "\xa3\xE1", + "loopz", + IMM, + 0, + 0, + "\xE1", + "0", + IMM, + CX, + 0, + "\xa1\xE1", + "0", + IMM, + ECX, + 0, + "\xa3\xE1", + "loopne", + IMM, + 0, + 0, + "\xE0", + "0", + IMM, + CX, + 0, + "\xa1\xE0", + "0", + IMM, + ECX, + 0, + "\xa3\xE0", + "loopnz", + IMM, + 0, + 0, + "\xE0", + "0", + IMM, + CX, + 0, + "\xa1\xE0", + "0", + IMM, + ECX, + 0, + "\xa3\xE0", + "lsl", + REG16, + R_M16, + O16 | _R, + "\x0F\x03", + "ltr", + R_M16, + 0, + _3, + "\x0F\x00", + "mov", + R_M8, + REG8, + _R, + "\x88", + "0", + R_M16, + REG16, + O16 | _R, + "\x89", + "0", + REG8, + R_M8, + _R, + "\x8A", + "0", + REG16, + R_M16, + O16 | _R, + "\x8B", + "0", + REG8, + IMM8, + PLUSREG | IB, + "\xB0", + "0", + REG16, + IMM16, + O16 | PLUSREG | IW, + "\xB8", + "0", + R_M8, + IMM8, + _0 | IB, + "\xC6", + "0", + R_M16, + IMM16, + O16 | _0 | IW, + "\xC7", + "movsb", + 0, + 0, + 0, + "\xA4", + "movsw", + 0, + 0, + O16, + "\xA5", + "movsx", + REG16, + R_M8, + O16 | _R, + "\x0F\xBE", + "movzx", + REG16, + R_M8, + O16 | _R, + "\x0F\xB6", + "mul", + R_M8, + 0, + _4, + "\xF6", + "0", + R_M16, + 0, + O16 | _4, + "\xF7", + "neg", + R_M8, + 0, + _3, + "\xF6", + "0", + R_M16, + 0, + O16 | _3, + "\xF7", + "not", + R_M8, + 0, + _2, + "\xF6", + "0", + R_M16, + 0, + O16 | _2, + "\xF7", + "nop", + 0, + 0, + 0, + "\x90", + "or", + R_M8, + REG8, + _R, + "\x08", + "0", + R_M16, + REG16, + O16 | _R, + "\x09", + "0", + REG8, + R_M8, + _R, + "\x0A", + "0", + REG16, + R_M16, + O16 | _R, + "\x0B", + "0", + R_M8, + IMM8, + _1 | IB, + "\x80", + "0", + R_M16, + IMM16, + O16 | _1 | IW, + "\x81", + "0", + R_M16, + IMM8, + O16 | _1 | IB, + "\x83", + "0", + AL, + IMM8, + IB, + "\x0C", + "0", + AX, + IMM16, + O16 | IW, + "\x0D", + "out", + IMM8, + AL, + IB, + "\xE6", + "0", + IMM8, + AX, + O16 | IB, + "\xE7", + "outsb", + 0, + 0, + 0, + "\x6E", + "outsw", + 0, + 0, + O16, + "\x6F", + "pop", + REG16, + 0, + O16 | PLUSREG, + "\x58", + "0", + R_M16, + 0, + O16 | _0, + "\x8F", + "popa", + 0, + 0, + 0, + "\x61", + "popaw", + 0, + 0, + O16, + "\x61", + "popf", + 0, + 0, + 0, + "\x9D", + "popfw", + 0, + 0, + O16, + "\x9D", + "push", + REG16, + 0, + O16 | PLUSREG, + "\x50", + "0", + R_M16, + 0, + O16 | _6, + "\xFF", + "0", + IMM8, + 0, + IB, + "\x6A", + "0", + IMM16, + 0, + O16 | IW, + "\x68", + "pusha", + 0, + 0, + 0, + "\x60", + "pushaw", + 0, + 0, + O16, + "\x60", + "pushf", + 0, + 0, + 0, + "\x9C", + "pushfw", + 0, + 0, + O16, + "\x9C", + "rcl", + R_M8, + CL, + _2, + "\xD2", + "0", + R_M8, + IMM8, + _2 | IB, + "\xC0", + "0", + R_M16, + CL, + O16 | _2, + "\xD3", + "0", + R_M16, + IMM8, + O16 | _2 | IB, + "\xC1", + "rcr", + R_M8, + CL, + _3, + "\xD2", + "0", + R_M8, + IMM8, + _3 | IB, + "\xC0", + "0", + R_M16, + CL, + O16 | _3, + "\xD3", + "0", + R_M16, + IMM8, + O16 | _3 | IB, + "\xC1", + "rdmsr", + 0, + 0, + 0, + "\x0F\x32", + "rdpmc", + 0, + 0, + 0, + "\x0F\x33", + "rdtsc", + 0, + 0, + 0, + "\x0F\x31", + "ret", + 0, + 0, + 0, + "\xC3", + "0", + IMM16, + 0, + IW, + "\xC2", + "retf", + 0, + 0, + 0, + "\xCB", + "0", + IMM16, + 0, + IW, + "\xCA", + "retn", + 0, + 0, + 0, + "\xC3", + "0", + IMM16, + 0, + IW, + "\xC2", + "rol", + R_M8, + CL, + _0, + "\xD2", + "0", + R_M8, + IMM8, + _0 | IB, + "\xC0", + "0", + R_M16, + CL, + O16 | _0, + "\xD3", + "0", + R_M16, + IMM8, + O16 | _0 | IB, + "\xC1", + "ror", + R_M8, + CL, + _1, + "\xD2", + "0", + R_M8, + IMM8, + _1 | IB, + "\xC0", + "0", + R_M16, + CL, + O16 | _1, + "\xD3", + "0", + R_M16, + IMM8, + O16 | _1 | IB, + "\xC1", + "rsm", + 0, + 0, + 0, + "\x0F\xAA", + "sahf", + 0, + 0, + 0, + "\x9E", + "sal", + R_M8, + CL, + _4, + "\xD2", + "0", + R_M8, + IMM8, + _4 | IB, + "\xC0", + "0", + R_M16, + CL, + O16 | _4, + "\xD3", + "0", + R_M16, + IMM8, + O16 | _4 | IB, + "\xC1", + "sar", + R_M8, + CL, + _0, + "\xD2", + "0", + R_M8, + IMM8, + _0 | IB, + "\xC0", + "0", + R_M16, + CL, + O16 | _0, + "\xD3", + "0", + R_M16, + IMM8, + O16 | _0 | IB, + "\xC1", + "salc", + 0, + 0, + 0, + "\xD6", + "sbb", + R_M8, + REG8, + _R, + "\x18", + "0", + R_M16, + REG16, + O16 | _R, + "\x19", + "0", + REG8, + R_M8, + _R, + "\x1A", + "0", + REG16, + R_M16, + O16 | _R, + "\x1B", + "0", + R_M8, + IMM8, + _3 | IB, + "\x80", + "0", + R_M16, + IMM16, + O16 | _3 | IW, + "\x81", + "0", + R_M16, + IMM8, + O16 | _3 | IB, + "\x83", + "0", + AL, + IMM8, + IB, + "\x1C", + "0", + AX, + IMM16, + O16 | IW, + "\x1D", + "scasb", + 0, + 0, + 0, + "\xAE", + "scasw", + 0, + 0, + O16, + "\xAF", + "setcc", + R_M8, + 0, + PLUSCC | _2, + "\x0F\x90", + "sgdt", + MEM, + 0, + _0, + "\x0F\x01", + "sidt", + MEM, + 0, + _1, + "\x0F\x01", + "sldt", + R_M16, + 0, + _0, + "\x0F\x00", + "shl", + R_M8, + CL, + _4, + "\xD2", + "0", + R_M8, + IMM8, + _4 | IB, + "\xC0", + "0", + R_M16, + CL, + O16 | _4, + "\xD3", + "0", + R_M16, + IMM8, + O16 | _4 | IB, + "\xC1", + "shr", + R_M8, + CL, + _5, + "\xD2", + "0", + R_M8, + IMM8, + _5 | IB, + "\xC0", + "0", + R_M16, + CL, + O16 | _5, + "\xD3", + "0", + R_M16, + IMM8, + O16 | _5 | IB, + "\xC1", + "smi", + 0, + 0, + 0, + "\xF1", + "smsw", + R_M16, + 0, + _4, + "\x0F\x01", + "stc", + 0, + 0, + 0, + "\xF9", + "std", + 0, + 0, + 0, + "\xFD", + "sti", + 0, + 0, + 0, + "\xFB", + "stosb", + 0, + 0, + 0, + "\xAA", + "stosw", + 0, + 0, + O16, + "\xAB", + "str", + R_M16, + 0, + _1, + "\x0F\x00", + "sub", + R_M8, + REG8, + _R, + "\x28", + "0", + R_M16, + REG16, + O16 | _R, + "\x29", + "0", + REG8, + R_M8, + _R, + "\x2A", + "0", + REG16, + R_M16, + O16 | _R, + "\x2B", + "0", + R_M8, + IMM8, + _5 | IB, + "\x80", + "0", + R_M16, + IMM16, + O16 | _5 | IW, + "\x81", + "0", + R_M16, + IMM8, + O16 | _5 | IB, + "\x83", + "0", + AL, + IMM8, + IB, + "\x2C", + "0", + AX, + IMM16, + O16 | IW, + "\x2D", + "test", + R_M8, + REG8, + _R, + "\x84", + "0", + R_M16, + REG16, + O16 | _R, + "\x85", + "0", + R_M8, + IMM8, + _7 | IB, + "\xF6", + "0", + R_M16, + IMM16, + O16 | _7 | IW, + "\xF7", + "0", + AL, + IMM8, + IB, + "\xA8", + "0", + AX, + IMM16, + O16 | IW, + "\xA9", + "umov", + R_M8, + REG8, + _R, + "\x0F\x10", + "0", + R_M16, + REG16, + O16 | _R, + "\x0F\x11", + "0", + REG8, + R_M8, + _R, + "\x0F\x12", + "0", + REG16, + R_M16, + O16 | _R, + "\x0F\x13", + "verr", + R_M16, + 0, + _4, + "\x0F\x00", + "verw", + R_M16, + 0, + _5, + "\x0F\x00", + "wait", + 0, + 0, + 0, + "\x9B", + "wbinvd", + 0, + 0, + 0, + "\x0F\x09", + "wrmsr", + 0, + 0, + 0, + "\x0F\x30", + "xadd", + R_M8, + REG8, + _R, + "\x0F\xC0", + "0", + R_M16, + REG16, + O16 | _R, + "\x0F\xC1", + "xbts", + REG16, + R_M16, + O16 | _R, + "\x0F\xA6", + "xchg", + REG8, + R_M8, + _R, + "\x86", + "0", + REG16, + R_M8, + O16 | _R, + "\x87", + "0", + R_M8, + REG8, + _R, + "\x86", + "0", + R_M16, + REG16, + O16 | _R, + "\x87", + "0", + AX, + REG16, + O16 | PLUSREG, + "\x90", + "0", + REG16, + AX, + O16 | PLUSREG, + "\x90", + "xlatb", + 0, + 0, + 0, + "\xD7", + "xor", + R_M8, + REG8, + _R, + "\x30", + "0", + R_M16, + REG16, + O16 | _R, + "\x31", + "0", + REG8, + R_M8, + _R, + "\x32", + "0", + REG16, + R_M16, + O16 | _R, + "\x33", + "0", + R_M8, + IMM8, + _6 | IB, + "\x80", + "0", + R_M16, + IMM16, + O16 | _6 | IW, + "\x81", + "0", + R_M16, + IMM8, + O16 | _6 | IB, + "\x83", + "0", + AL, + IMM8, + IB, + "\x34", + "0", + AX, + IMM16, + O16 | IW, + "\x35", + 0, + 0, + 0, + 0, + 0}; diff --git a/compiler/gen/main.cpp b/compiler/gen/main.cpp new file mode 100644 index 0000000..f9b33d9 --- /dev/null +++ b/compiler/gen/main.cpp @@ -0,0 +1,194 @@ + +/* + + This generates a source code file for x86 instruction formats. + + Thanks NASM! + +*/ + +#include +#include +#include +#include + +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(); +} diff --git a/compiler/gen/nasm_insts.txt b/compiler/gen/nasm_insts.txt new file mode 100644 index 0000000..619ec24 --- /dev/null +++ b/compiler/gen/nasm_insts.txt @@ -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] diff --git a/compiler/label.hpp b/compiler/label.hpp deleted file mode 100644 index f932ba0..0000000 --- a/compiler/label.hpp +++ /dev/null @@ -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 \ No newline at end of file diff --git a/compiler/lib/CMakeLists.txt b/compiler/lib/CMakeLists.txt new file mode 100644 index 0000000..b84a967 --- /dev/null +++ b/compiler/lib/CMakeLists.txt @@ -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() diff --git a/compiler/lib/assem.hpp b/compiler/lib/assem.hpp new file mode 100644 index 0000000..d14d613 --- /dev/null +++ b/compiler/lib/assem.hpp @@ -0,0 +1,12 @@ +#pragma once +#include + +#include + +class Assem { + public: + std::istream& in; + Module* mod; + Assem(std::istream& in, Module* mod) : in(in), mod(mod) {} + virtual void assemble() = 0; +}; diff --git a/compiler/assem_x86/assem_x86.cpp b/compiler/lib/assem_x86/assem_x86.cpp similarity index 79% rename from compiler/assem_x86/assem_x86.cpp rename to compiler/lib/assem_x86/assem_x86.cpp index 499a6a9..186fc0c 100644 --- a/compiler/assem_x86/assem_x86.cpp +++ b/compiler/lib/assem_x86/assem_x86.cpp @@ -1,27 +1,24 @@ +/* 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 +#include "../ex.hpp" +#include "insts.hpp" +#include "operand.hpp" +#include #include -typedef map InstMap; -typedef InstMap::value_type InstPair; -typedef InstMap::const_iterator InstIter; +typedef std::map InstMap; +typedef InstMap::value_type InstPair; +typedef InstMap::const_iterator InstIter; 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 ops; + int i = 0; + std::string name; + std::vector 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); } } } diff --git a/compiler/lib/assem_x86/assem_x86.hpp b/compiler/lib/assem_x86/assem_x86.hpp new file mode 100644 index 0000000..6ca735f --- /dev/null +++ b/compiler/lib/assem_x86/assem_x86.hpp @@ -0,0 +1,29 @@ +#pragma once +#include +#include +#include +#include +#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); +}; diff --git a/compiler/lib/assem_x86/insts.cpp b/compiler/lib/assem_x86/insts.cpp new file mode 100644 index 0000000..1059065 --- /dev/null +++ b/compiler/lib/assem_x86/insts.cpp @@ -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 +}; diff --git a/compiler/assem_x86/insts.h b/compiler/lib/assem_x86/insts.hpp similarity index 94% rename from compiler/assem_x86/insts.h rename to compiler/lib/assem_x86/insts.hpp index 59b1cfe..76a87df 100644 --- a/compiler/assem_x86/insts.h +++ b/compiler/lib/assem_x86/insts.hpp @@ -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 diff --git a/compiler/assem_x86/operand.cpp b/compiler/lib/assem_x86/operand.cpp similarity index 89% rename from compiler/assem_x86/operand.cpp rename to compiler/lib/assem_x86/operand.cpp index 03b551a..8ac6394 100644 --- a/compiler/assem_x86/operand.cpp +++ b/compiler/lib/assem_x86/operand.cpp @@ -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; @@ -181,11 +181,11 @@ void Operand::parse() mode |= MEM32 | R_M32; for (;;) { - int n; - string l; + int n; + 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) diff --git a/compiler/lib/assem_x86/operand.hpp b/compiler/lib/assem_x86/operand.hpp new file mode 100644 index 0000000..0406ee4 --- /dev/null +++ b/compiler/lib/assem_x86/operand.hpp @@ -0,0 +1,24 @@ +#pragma once +#include +#include + +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); +}; diff --git a/compiler/bb_tech.txt b/compiler/lib/bb_tech.txt similarity index 100% rename from compiler/bb_tech.txt rename to compiler/lib/bb_tech.txt diff --git a/compiler/codegen.hpp b/compiler/lib/codegen.hpp similarity index 62% rename from compiler/codegen.hpp rename to compiler/lib/codegen.hpp index e802716..e221be4 100644 --- a/compiler/codegen.hpp +++ b/compiler/lib/codegen.hpp @@ -1,8 +1,6 @@ - -#ifndef CODEGEN_H -#define CODEGEN_H - -#include "std.hpp" +#pragma once +#include +#include 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 \ No newline at end of file diff --git a/compiler/codegen_x86/codegen_x86.cpp b/compiler/lib/codegen_x86/codegen_x86.cpp similarity index 77% rename from compiler/codegen_x86/codegen_x86.cpp rename to compiler/lib/codegen_x86/codegen_x86.cpp index e3b4d71..44aa50b 100644 --- a/compiler/codegen_x86/codegen_x86.cpp +++ b/compiler/lib/codegen_x86/codegen_x86.cpp @@ -1,13 +1,135 @@ +#include "codegen_x86.hpp" +#include "tile.hpp" +#include +#include -#include "codegen_x86.h" -#include "../std.h" -#include "tile.h" +#include //#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::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::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) { diff --git a/compiler/lib/codegen_x86/codegen_x86.hpp b/compiler/lib/codegen_x86/codegen_x86.hpp new file mode 100644 index 0000000..34e9ec4 --- /dev/null +++ b/compiler/lib/codegen_x86/codegen_x86.hpp @@ -0,0 +1,40 @@ +#pragma once +#include "../codegen.hpp" +#include +#include + +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); +}; \ No newline at end of file diff --git a/compiler/codegen_x86/tile.cpp b/compiler/lib/codegen_x86/tile.cpp similarity index 50% rename from compiler/codegen_x86/tile.cpp rename to compiler/lib/codegen_x86/tile.cpp index 33abd03..2985e2c 100644 --- a/compiler/codegen_x86/tile.cpp +++ b/compiler/lib/codegen_x86/tile.cpp @@ -1,32 +1,33 @@ +#include "tile.hpp" +#include +#include +#include "codegen_x86.hpp" -#include "tile.h" -#include "../std.h" -#include "codegen_x86.h" +#include //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 codeFrags, dataFrags; +std::vector 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::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::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'); -} diff --git a/compiler/lib/codegen_x86/tile.hpp b/compiler/lib/codegen_x86/tile.hpp new file mode 100644 index 0000000..ca37f47 --- /dev/null +++ b/compiler/lib/codegen_x86/tile.hpp @@ -0,0 +1,32 @@ +#pragma once +#include +#include + +enum { EAX = 1, ECX, EDX, EDI, ESI, EBX }; + +extern std::vector 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; +}; diff --git a/compiler/decl.cpp b/compiler/lib/decl.cpp similarity index 60% rename from compiler/decl.cpp rename to compiler/lib/decl.cpp index 6cfcd65..6aca477 100644 --- a/compiler/decl.cpp +++ b/compiler/lib/decl.cpp @@ -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::iterator it; + std::vector::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(); +} diff --git a/compiler/lib/decl.hpp b/compiler/lib/decl.hpp new file mode 100644 index 0000000..faa911b --- /dev/null +++ b/compiler/lib/decl.hpp @@ -0,0 +1,36 @@ +#pragma once +#include +#include + +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 decls; + DeclSeq(); + ~DeclSeq(); + Decl* findDecl(const std::string& s); + Decl* insertDecl(const std::string& s, Type* t, int kind, ConstType* d = 0); + int size(); +}; diff --git a/compiler/declnode.cpp b/compiler/lib/declnode.cpp similarity index 79% rename from compiler/declnode.cpp rename to compiler/lib/declnode.cpp index 21af61d..fcd0157 100644 --- a/compiler/declnode.cpp +++ b/compiler/lib/declnode.cpp @@ -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 +#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 @@ -243,9 +296,9 @@ void StructDeclNode::translate(Codegen* g) //type of each field for (k = 0; k < sem_type->fields->size(); ++k) { - Decl* field = sem_type->fields->decls[k]; - Type* type = field->type; - string t; + Decl* field = sem_type->fields->decls[k]; + Type* type = field->type; + 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 sizes; + std::vector sizes; for (int k = 0; k < exprs->size(); ++k) { ExprNode* e = exprs->exprs[k] = exprs->exprs[k]->semant(env); ConstNode* c = e->constNode(); @@ -319,8 +388,8 @@ void VectorDeclNode::proto(DeclSeq* d, Environ* env) ex("Blitz array sizes must not be negative"); sizes.push_back(n + 1); } - string label = genLabel(); - sem_type = new VectorType(label, ty, sizes); + std::string label = genLabel(); + sem_type = new VectorType(label, ty, sizes); if (!d->insertDecl(ident, sem_type, kind)) { delete sem_type; ex("Duplicate identifier"); @@ -338,8 +407,8 @@ 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; - Type* type = v->elementType; + std::string t; + Type* type = v->elementType; if (type == Type::int_type) t = "__bbIntType"; else if (type == Type::float_type) @@ -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) {} diff --git a/compiler/lib/declnode.hpp b/compiler/lib/declnode.hpp new file mode 100644 index 0000000..768ceea --- /dev/null +++ b/compiler/lib/declnode.hpp @@ -0,0 +1,95 @@ +#pragma once +#include +#include +#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 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); +}; diff --git a/compiler/environ.cpp b/compiler/lib/environ.cpp similarity index 71% rename from compiler/environ.cpp rename to compiler/lib/environ.cpp index 61a6f06..bb427de 100644 --- a/compiler/environ.cpp +++ b/compiler/lib/environ.cpp @@ -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; } diff --git a/compiler/lib/environ.hpp b/compiler/lib/environ.hpp new file mode 100644 index 0000000..e7b7978 --- /dev/null +++ b/compiler/lib/environ.hpp @@ -0,0 +1,38 @@ +/* An environ represent a stack frame block. */ + +#pragma once +#include +#include +#include + +struct Decl; +struct DeclSeq; +struct Label; +struct Type; + +class Environ { + public: + int level; + DeclSeq* decls; + DeclSeq* funcDecls; + DeclSeq* typeDecls; + + std::vector types; + + std::vector labels; + Environ* globals; + Type* returnType; + std::string funcLabel, breakLabel; + std::list 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); +}; diff --git a/compiler/lib/ex.hpp b/compiler/lib/ex.hpp new file mode 100644 index 0000000..9095272 --- /dev/null +++ b/compiler/lib/ex.hpp @@ -0,0 +1,10 @@ +#pragma once +#include + +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) {} +}; diff --git a/compiler/exprnode.cpp b/compiler/lib/exprnode.cpp similarity index 88% rename from compiler/exprnode.cpp rename to compiler/lib/exprnode.cpp index b2a093a..2ca02b9 100644 --- a/compiler/exprnode.cpp +++ b/compiler/lib/exprnode.cpp @@ -1,9 +1,16 @@ +#include "exprnode.hpp" +#include +#include +#include "codegen.hpp" +#include "environ.hpp" +#include "toker.hpp" +#include "varnode.hpp" -#include "nodes.hpp" -#include "std.hpp" +#include -#include -#include +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 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; +} diff --git a/compiler/exprnode.hpp b/compiler/lib/exprnode.hpp similarity index 51% rename from compiler/exprnode.hpp rename to compiler/lib/exprnode.hpp index 5da4f06..00bd92a 100644 --- a/compiler/exprnode.hpp +++ b/compiler/lib/exprnode.hpp @@ -1,15 +1,24 @@ - -#ifndef EXPRNODE_H -#define EXPRNODE_H - +#pragma once +#include +#include +#include #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 sem_type; + + + public: + ExprNode(); + ExprNode(std::shared_ptr t); ExprNode* castTo(Type* ty, Environ* e); ExprNode* semant(Environ* e, Type* ty); @@ -22,114 +31,92 @@ struct ExprNode : public Node { } }; -struct ExprSeqNode : public Node { - vector exprs; - ~ExprSeqNode() - { - for (; exprs.size(); exprs.pop_back()) - delete exprs.back(); - } - void push_back(ExprNode* e) - { - exprs.push_back(e); - } - int size() - { - return exprs.size(); - } - void semant(Environ* e); - TNode* translate(Codegen* g, bool userlib); - void castTo(DeclSeq* ds, Environ* e, bool userlib); - void castTo(Type* t, Environ* e); -}; +class ExprSeqNode : public Node { + std::list> exprs; -#include "varnode.hpp" + public: + ~ExprSeqNode(); + + void push_back(std::shared_ptr e); + + int size(); + + void semant(Environ* e); + + TNode* translate(Codegen* g, bool userlib); + + void castTo(DeclSeq* ds, Environ* e, bool userlib); + + void castTo(Type* t, Environ* e); +}; struct CastNode : public ExprNode { 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; - } - virtual int intValue() = 0; - virtual float floatValue() = 0; - virtual string stringValue() = 0; + ExprNode* semant(Environ* e); + ConstNode* constNode(); + virtual int intValue() = 0; + virtual float floatValue() = 0; + virtual std::string stringValue() = 0; }; struct IntConstNode : public ConstNode { int value; IntConstNode(int n); - TNode* translate(Codegen* g); - int intValue(); - float floatValue(); - string stringValue(); + TNode* translate(Codegen* g); + int intValue(); + float floatValue(); + std::string stringValue(); }; struct FloatConstNode : public ConstNode { float value; FloatConstNode(float f); - TNode* translate(Codegen* g); - int intValue(); - float floatValue(); - string stringValue(); + TNode* translate(Codegen* g); + int intValue(); + float floatValue(); + std::string stringValue(); }; struct StringConstNode : public ConstNode { - string value; - StringConstNode(const string& s); - TNode* translate(Codegen* g); - int intValue(); - float floatValue(); - string stringValue(); + std::string value; + StringConstNode(const std::string& s); + TNode* translate(Codegen* g); + int intValue(); + float floatValue(); + 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); }; @@ -227,26 +196,18 @@ 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; - } + ExprNode* 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 diff --git a/compiler/ir_code.txt b/compiler/lib/ir_code.txt similarity index 100% rename from compiler/ir_code.txt rename to compiler/lib/ir_code.txt diff --git a/compiler/lib/label.hpp b/compiler/lib/label.hpp new file mode 100644 index 0000000..5658a28 --- /dev/null +++ b/compiler/lib/label.hpp @@ -0,0 +1,10 @@ +#pragma once +#include + +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) {} +}; diff --git a/compiler/node.cpp b/compiler/lib/node.cpp similarity index 84% rename from compiler/node.cpp rename to compiler/lib/node.cpp index 2c7b9a6..38dfe8d 100644 --- a/compiler/node.cpp +++ b/compiler/lib/node.cpp @@ -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 Node::usedfuncs; +#include + +std::set 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,8 +41,8 @@ void Node::ex(const string& e, int pos, const string& f) /////////////////////////////// VarNode* Node::genLocal(Environ* e, Type* ty) { - string t = genLabel(); - Decl* d = e->decls->insertDecl(t, ty, DECL_LOCAL); + std::string t = genLabel(); + Decl* d = e->decls->insertDecl(t, ty, DECL_LOCAL); return new DeclVarNode(d); } @@ -119,9 +128,9 @@ TNode* Node::deleteVars(Environ* e) { TNode *t = 0, *l = 0, *p, *p1 = nullptr, *p2 = nullptr; for (int k = 0; k < e->decls->size(); ++k) { - Decl* d = e->decls->decls[k]; - Type* type = d->type; - string func; + Decl* d = e->decls->decls[k]; + Type* type = d->type; + 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); } diff --git a/compiler/lib/node.hpp b/compiler/lib/node.hpp new file mode 100644 index 0000000..d12cddf --- /dev/null +++ b/compiler/lib/node.hpp @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include "type.hpp" + +struct VarNode; +struct ConstNode; +class Environ; +struct TNode; + +class Node { + public: + virtual ~Node() {} + + public: + //used user funcs... + static std::set 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); +}; diff --git a/compiler/nodes.hpp b/compiler/lib/nodes.hpp similarity index 69% rename from compiler/nodes.hpp rename to compiler/lib/nodes.hpp index a84e764..0e9996a 100644 --- a/compiler/nodes.hpp +++ b/compiler/lib/nodes.hpp @@ -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 diff --git a/compiler/parser.cpp b/compiler/lib/parser.cpp similarity index 74% rename from compiler/parser.cpp rename to compiler/lib/parser.cpp index f74c4e2..f40005d 100644 --- a/compiler/parser.cpp +++ b/compiler/lib/parser.cpp @@ -1,13 +1,14 @@ - #include "parser.hpp" #include -#include "std.hpp" +#include +#include "ex.hpp" + +#include "varnode.hpp" + +#include +#include -#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 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(); + structs = std::make_shared(); + funcs = std::make_shared(); + datas = std::make_shared(); - try { - stmts = parseStmtSeq(STMTS_PROG); - if (toker->curr() != EOF) - exp("end-of-file"); - } catch (Ex) { - delete stmts; - delete datas; - delete funcs; - delete structs; - delete consts; - throw; + std::shared_ptr stmts; + + stmts = parseStmtSeq(STMTS_PROG); + if (toker->curr() != EOF) { + exp("end-of-file"); } - return new ProgNode(consts, structs, funcs, datas, stmts); + return std::make_shared(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 Parser::parseStmtSeq(int scope) { - a_ptr stmts(new StmtSeqNode(incfile)); + std::shared_ptr stmts = std::make_shared(incfile); parseStmtSeq(stmts, scope); - return stmts.release(); + return stmts; } -void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope) +void Parser::parseStmtSeq(std::shared_ptr 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 i_toker = std::make_shared(i_stream); + std::swap(this->toker, i_toker); included.insert(incfile); - a_ptr ss(parseStmtSeq(scope)); - if (toker->curr() != EOF) + std::shared_ptr 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 expr(parseExpr(false)); - a_ptr stmts(parseStmtSeq(STMTS_BLOCK)); - int pos = toker->pos(); + std::shared_ptr expr = parseExpr(false); + std::shared_ptr 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,9 +250,9 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope) exp("variable assignment"); if (toker->next() == EACH) { toker->next(); - string ident = parseIdent(); - stmts = parseStmtSeq(STMTS_BLOCK); - int pos = toker->pos(); + std::string ident = parseIdent(); + stmts = parseStmtSeq(STMTS_BLOCK); + int pos = toker->pos(); if (toker->curr() != NEXT) exp("'Next'"); toker->next(); @@ -295,13 +284,13 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope) } break; case GOTO: { toker->next(); - string t = parseIdent(); - result = new GotoNode(t); + std::string t = parseIdent(); + result = new GotoNode(t); } break; case GOSUB: { toker->next(); - string t = parseIdent(); - result = new GosubNode(t); + std::string t = parseIdent(); + result = new GosubNode(t); } break; case RETURN: { toker->next(); @@ -310,8 +299,8 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope) case BBDELETE: { if (toker->next() == EACH) { toker->next(); - string t = parseIdent(); - result = new DeleteEachNode(t); + std::string t = parseIdent(); + result = new DeleteEachNode(t); } else { ExprNode* expr = parseExpr(false); result = new DeleteNode(expr); @@ -406,8 +395,8 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope) break; case '.': { toker->next(); - string t = parseIdent(); - result = new LabelNode(t, datas->size()); + std::string t = parseIdent(); + result = new LabelNode(t, datas->size()); } break; default: return; @@ -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 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 Parser::parseVar(const std::string& ident, const std::string& tag) { a_ptr var; if (toker->curr() == '(') { @@ -462,10 +451,10 @@ VarNode* Parser::parseVar(const string& ident, const string& tag) for (;;) { if (toker->curr() == '\\') { toker->next(); - string ident = parseIdent(); - string tag = parseTypeTag(); - ExprNode* expr = new VarExprNode(var.release()); - var = new FieldVarNode(expr, ident, tag); + std::string ident = parseIdent(); + std::string tag = parseTypeTag(); + ExprNode* expr = new VarExprNode(var.release()); + var = new FieldVarNode(expr, ident, tag); } else if (toker->curr() == '[') { toker->next(); a_ptr exprs(parseExprSeq()); @@ -481,12 +470,12 @@ VarNode* Parser::parseVar(const string& ident, const string& tag) return var.release(); } -DeclNode* Parser::parseVarDecl(int kind, bool constant) +std::shared_ptr Parser::parseVarDecl(int kind, bool constant) { - int pos = toker->pos(); - string ident = parseIdent(); - string tag = parseTypeTag(); - DeclNode* d; + int pos = toker->pos(); + std::string ident = parseIdent(); + std::string tag = parseTypeTag(); + DeclNode* d; if (toker->curr() == '[') { if (constant) ex("Blitz arrays may not be constant"); @@ -510,11 +499,11 @@ DeclNode* Parser::parseVarDecl(int kind, bool constant) return d; } -DimNode* Parser::parseArrayDecl() +std::shared_ptr Parser::parseArrayDecl() { - int pos = toker->pos(); - string ident = parseIdent(); - string tag = parseTypeTag(); + int pos = toker->pos(); + 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 Parser::parseFuncDecl() { - int pos = toker->pos(); - string ident = parseIdent(); - string tag = parseTypeTag(); + int pos = toker->pos(); + std::string ident = parseIdent(); + std::string tag = parseTypeTag(); if (toker->curr() != '(') exp("'('"); a_ptr params(new DeclSeqNode()); @@ -562,10 +551,10 @@ DeclNode* Parser::parseFuncDecl() return d; } -DeclNode* Parser::parseStructDecl() +std::shared_ptr Parser::parseStructDecl() { - int pos = toker->pos(); - string ident = parseIdent(); + int pos = toker->pos(); + std::string ident = parseIdent(); while (toker->curr() == '\n') toker->next(); a_ptr fields(new DeclSeqNode()); @@ -586,7 +575,7 @@ DeclNode* Parser::parseStructDecl() return d; } -IfNode* Parser::parseIf() +std::shared_ptr Parser::parseIf() { a_ptr expr; a_ptr stmts, elseOpt; @@ -618,124 +607,145 @@ IfNode* Parser::parseIf() return new IfNode(expr.release(), stmts.release(), elseOpt.release()); } -ExprSeqNode* Parser::parseExprSeq() +std::shared_ptr Parser::parseExprSeq() { - a_ptr exprs(new ExprSeqNode()); + std::shared_ptr exprs = std::make_shared(); bool opt = true; - while (ExprNode* e = parseExpr(opt)) { + while (std::shared_ptr 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 Parser::parseExpr(bool opt) { if (toker->curr() == NOT) { toker->next(); - ExprNode* expr = parseExpr1(false); - return new RelExprNode('=', expr, new IntConstNode(0)); + std::shared_ptr expr = parseExpr1(false); + return std::make_shared('=', expr, std::make_shared(0)); } return parseExpr1(opt); } -ExprNode* Parser::parseExpr1(bool opt) +std::shared_ptr Parser::parseExpr1(bool opt) { - a_ptr lhs(parseExpr2(opt)); + std::shared_ptr rhs; + std::shared_ptr 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(c, lhs, rhs); } } -ExprNode* Parser::parseExpr2(bool opt) +std::shared_ptr Parser::parseExpr2(bool opt) { - a_ptr lhs(parseExpr3(opt)); + std::shared_ptr rhs; + std::shared_ptr 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(c, lhs, rhs); } } -ExprNode* Parser::parseExpr3(bool opt) +std::shared_ptr Parser::parseExpr3(bool opt) { - a_ptr lhs(parseExpr4(opt)); + std::shared_ptr rhs; + std::shared_ptr 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(c, lhs, rhs); } } -ExprNode* Parser::parseExpr4(bool opt) +std::shared_ptr Parser::parseExpr4(bool opt) { - a_ptr lhs(parseExpr5(opt)); + std::shared_ptr rhs; + std::shared_ptr 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(c, lhs, rhs); } } -ExprNode* Parser::parseExpr5(bool opt) +std::shared_ptr Parser::parseExpr5(bool opt) { - a_ptr lhs(parseExpr6(opt)); - if (!lhs) + std::shared_ptr rhs; + std::shared_ptr 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(c, lhs, rhs); } } -ExprNode* Parser::parseExpr6(bool opt) +std::shared_ptr Parser::parseExpr6(bool opt) { - a_ptr lhs(parseUniExpr(opt)); - if (!lhs) - return 0; + std::shared_ptr rhs; + std::shared_ptr 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(c, lhs, rhs); } } -ExprNode* Parser::parseUniExpr(bool opt) +std::shared_ptr Parser::parseUniExpr(bool opt) { - ExprNode* result = 0; - string t; + std::shared_ptr 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 Parser::parsePrimary(bool opt) { a_ptr expr; - string t, ident, tag; + std::string t, ident, tag; ExprNode* result = 0; int n, k; diff --git a/compiler/lib/parser.hpp b/compiler/lib/parser.hpp new file mode 100644 index 0000000..7d856f1 --- /dev/null +++ b/compiler/lib/parser.hpp @@ -0,0 +1,63 @@ +/* + + The parser builds an abstact syntax tree from input tokens. + +*/ + +#pragma once +#include +#include +#include +#include +#include "nodes.hpp" +#include "toker.hpp" + +class Parser { + std::string incfile; + std::set included; + std::map arrayDecls; + std::shared_ptr toker; + std::shared_ptr main_toker; + std::shared_ptr consts; + std::shared_ptr structs; + std::shared_ptr funcs; + std::shared_ptr datas; + + std::shared_ptr parseStmtSeq(int scope); + void parseStmtSeq(std::shared_ptr 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 parseVar(); + std::shared_ptr parseVar(const std::string& ident, const std::string& tag); + std::shared_ptr parseCall(const std::string& ident, const std::string& tag); + std::shared_ptr parseIf(); + + std::shared_ptr parseVarDecl(int kind, bool constant); + std::shared_ptr parseArrayDecl(); + std::shared_ptr parseFuncDecl(); + std::shared_ptr parseStructDecl(); + + std::shared_ptr parseExprSeq(); + + std::shared_ptr parseExpr(bool opt); + std::shared_ptr parseExpr1(bool opt); //And, Or, Eor + std::shared_ptr parseExpr2(bool opt); //<,=,>,<=,<>,>= + std::shared_ptr parseExpr3(bool opt); //+,- + std::shared_ptr parseExpr4(bool opt); //Lsr,Lsr,Asr + std::shared_ptr parseExpr5(bool opt); //*,/,Mod + std::shared_ptr parseExpr6(bool opt); //^ + std::shared_ptr parseUniExpr(bool opt); //+,-,Not,~ + std::shared_ptr parsePrimary(bool opt); + + public: + Parser(Toker& t); + ~Parser(); + + std::shared_ptr parse(std::string const& main); +}; diff --git a/compiler/prognode.cpp b/compiler/lib/prognode.cpp similarity index 64% rename from compiler/prognode.cpp rename to compiler/lib/prognode.cpp index c77bac1..2c1e1ef 100644 --- a/compiler/prognode.cpp +++ b/compiler/lib/prognode.cpp @@ -1,17 +1,38 @@ +#include "prognode.hpp" +#include +#include "codegen.hpp" +#include "declnode.hpp" +#include "environ.hpp" +#include "label.hpp" +#include "stmtnode.hpp" -#include "nodes.hpp" -#include "std.hpp" +#include + +ProgNode::ProgNode(std::shared_ptr constants, std::shared_ptr structures, + std::shared_ptr functions, std::shared_ptr datas, + std::shared_ptr 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 ProgNode::semant(Environ* e) { file_lab = genLabel(); StmtSeqNode::reset(stmts->file, file_lab); - a_ptr env(new Environ(genLabel(), Type::int_type, 0, e)); + std::shared_ptr env = std::make_shared(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& usrfuncs) +void ProgNode::translate(Codegen* g, const std::vector& usrfuncs) { int k; @@ -55,7 +76,7 @@ void ProgNode::translate(Codegen* g, const vector& usrfuncs) if (t) g->code(t); if (g->debug) { - string t = genLabel(); + std::string t = genLabel(); g->s_data("
", t); g->code(call("__bbDebugEnter", local(0), iconst((int)sem_env), global(t))); } @@ -92,7 +113,7 @@ void ProgNode::translate(Codegen* g, const vector& usrfuncs) datas->translate(g); //library functions - map> libFuncs; + std::map> libFuncs; //lib ptrs g->flush(); @@ -111,12 +132,12 @@ void ProgNode::translate(Codegen* g, const vector& usrfuncs) //LIBS chunk g->flush(); g->label("__LIBS"); - map>::const_iterator lf_it; + std::map>::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& fns = lf_it->second; + const std::vector& 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& 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) +{} diff --git a/compiler/lib/prognode.hpp b/compiler/lib/prognode.hpp new file mode 100644 index 0000000..f9a44f2 --- /dev/null +++ b/compiler/lib/prognode.hpp @@ -0,0 +1,35 @@ +#pragma once +#include +#include +#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 consts; + std::shared_ptr structs; + std::shared_ptr funcs; + std::shared_ptr datas; + std::shared_ptr stmts; + std::shared_ptr sem_env; + + std::string file_lab; + + public: + ProgNode(std::shared_ptr constants, std::shared_ptr structures, std::shared_ptr functions, + std::shared_ptr datas, std::shared_ptr statements); + ~ProgNode(); + + std::shared_ptr semant(Environ* e); + + void translate(Codegen* g, const std::vector& userfuncs); +}; diff --git a/compiler/readme.txt b/compiler/lib/readme.txt similarity index 100% rename from compiler/readme.txt rename to compiler/lib/readme.txt diff --git a/compiler/stmtnode.cpp b/compiler/lib/stmtnode.cpp similarity index 74% rename from compiler/stmtnode.cpp rename to compiler/lib/stmtnode.cpp index 172befc..471dc62 100644 --- a/compiler/stmtnode.cpp +++ b/compiler/lib/stmtnode.cpp @@ -1,9 +1,17 @@ +#include "stmtnode.hpp" +#include +#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 fileMap; -static string fileLabel; -static map 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; - fileLabel = file.size() ? fileMap[file] : ""; + 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 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,21 +390,29 @@ 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 // ///////////////////// void WhileNode::semant(Environ* e) { - expr = expr->semant(e); - expr = expr->castTo(Type::int_type, e); - string brk = e->setBreak(sem_brk = genLabel()); + expr = expr->semant(e); + expr = expr->castTo(Type::int_type, e); + 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 labs; - string brk = genLabel(); + std::vector 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); + sem_brk = genLabel(); + 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; +} diff --git a/compiler/lib/stmtnode.hpp b/compiler/lib/stmtnode.hpp new file mode 100644 index 0000000..83fc33d --- /dev/null +++ b/compiler/lib/stmtnode.hpp @@ -0,0 +1,243 @@ +#pragma once +#include +#include +#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 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 stmts; + + public: + IncludeNode(const std::string& t, std::shared_ptr 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 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); +}; diff --git a/compiler/tnode.txt b/compiler/lib/tnode.txt similarity index 100% rename from compiler/tnode.txt rename to compiler/lib/tnode.txt diff --git a/compiler/todo.txt b/compiler/lib/todo.txt similarity index 100% rename from compiler/todo.txt rename to compiler/lib/todo.txt diff --git a/compiler/toker.cpp b/compiler/lib/toker.cpp similarity index 92% rename from compiler/toker.cpp rename to compiler/lib/toker.cpp index 0d18de7..a6e4dfc 100644 --- a/compiler/toker.cpp +++ b/compiler/lib/toker.cpp @@ -1,12 +1,12 @@ - #include "toker.hpp" #include #include "ex.hpp" -#include "std.hpp" + +#include int Toker::chars_toked; -static map alphaTokes, lowerTokes; +static std::map alphaTokes, lowerTokes; static void makeKeywords() { @@ -81,20 +81,20 @@ static void makeKeywords() alphaTokes["Shr"] = SHR; alphaTokes["Sar"] = SAR; - map::const_iterator it; + std::map::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& Toker::getKeywords() +std::map& 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::iterator it = lowerTokes.find(ident); + std::map::iterator it = lowerTokes.find(ident); if (it == lowerTokes.end()) { for (int n = from; n < k; ++n) diff --git a/compiler/toker.hpp b/compiler/lib/toker.hpp similarity index 66% rename from compiler/toker.hpp rename to compiler/lib/toker.hpp index 443120f..6a658a9 100644 --- a/compiler/toker.hpp +++ b/compiler/lib/toker.hpp @@ -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 +#include +#include +#include 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(); - int lookAhead(int n); + int pos(); + int curr(); + int next(); + std::string text(); + int lookAhead(int n); static int chars_toked; - static map& getKeywords(); + static std::map& 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 tokes; - void nextline(); - int curr_row, curr_toke; + std::istream& in; + std::string line; + std::vector tokes; + void nextline(); + int curr_row, curr_toke; }; - -#endif diff --git a/compiler/lib/type.cpp b/compiler/lib/type.cpp new file mode 100644 index 0000000..fbe61a9 --- /dev/null +++ b/compiler/lib/type.cpp @@ -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 t) +{ + return this == t.get(); +} + +std::shared_ptr Type::funcType() +{ + return std::shared_ptr(); +} + +std::shared_ptr Type::arrayType() +{ + return std::shared_ptr(); +} + +std::shared_ptr Type::structType() +{ + return std::shared_ptr(); +} + +std::shared_ptr Type::constType() +{ + return std::shared_ptr(); +} + +std::shared_ptr Type::vectorType() +{ + return std::shared_ptr(); +} + +FuncType::FuncType(std::shared_ptr return_type, std::shared_ptr 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() +{ + return std::dynamic_pointer_cast(this->shared_from_this()); +} + +ArrayType::ArrayType(std::shared_ptr t, int n) : type(t), size(n) {} + +ArrayType::~ArrayType() {} + +std::shared_ptr ArrayType::arrayType() +{ + return std::dynamic_pointer_cast(this->shared_from_this()); +} + +StructType::StructType(const std::string& i) : ident(i) {} + +StructType::StructType(const std::string& i, std::shared_ptr f) : ident(i), fields(f) {} + +StructType::~StructType() {} + +std::shared_ptr StructType::structType() +{ + return std::dynamic_pointer_cast(this->shared_from_this()); +} + +bool StructType::canCastTo(std::shared_ptr 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() +{ + return std::dynamic_pointer_cast(this->shared_from_this()); +} + +VectorType::VectorType(const std::string& l, Type* t, const std::vector& szs) + : label(l), elementType(t), sizes(szs) +{} + +VectorType::~VectorType() {} + +std::shared_ptr VectorType::vectorType() +{ + return std::dynamic_pointer_cast(this->shared_from_this()); +} + +bool VectorType::canCastTo(std::shared_ptr t) +{ + if (this == t.get()) { + return true; + } + + std::shared_ptr 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 t) override { + return t == Type::void_type; + } +}; +std::shared_ptr Type::void_type = std::make_shared(); + +class IntType : public Type { + virtual bool intType() override { + return true; + } + + virtual bool canCastTo(std::shared_ptr t) override + { + return t == Type::int_type; + } +}; +std::shared_ptr Type::int_type = std::make_shared(); + +class FloatType : public Type { + virtual bool floatType() override + { + return true; + } + + virtual bool canCastTo(std::shared_ptr t) override + { + return t == Type::float_type; + } +}; +std::shared_ptr Type::float_type = std::make_shared(); + +class StringType : public Type { + virtual bool stringType() override + { + return true; + } + + virtual bool canCastTo(std::shared_ptr t) override + { + return t == Type::string_type; + } +}; +std::shared_ptr Type::string_type = std::make_shared(); + +std::shared_ptr Type::string_type = std::make_shared("Null"); diff --git a/compiler/lib/type.hpp b/compiler/lib/type.hpp new file mode 100644 index 0000000..d59e77e --- /dev/null +++ b/compiler/lib/type.hpp @@ -0,0 +1,110 @@ +#pragma once +#include +#include +#include +#include +#include +#include "decl.hpp" + +class FuncType; +class ArrayType; +class StructType; +class ConstType; +class VectorType; +class DeclSeq; + +class Type : public std::enable_shared_from_this { + public: + Type(); + virtual ~Type(); + + virtual bool intType(); + virtual bool floatType(); + virtual bool stringType(); + + //operators + virtual bool canCastTo(std::shared_ptr t); + + //casts to inherited types + virtual std::shared_ptr funcType(); + virtual std::shared_ptr arrayType(); + virtual std::shared_ptr structType(); + virtual std::shared_ptr constType(); + virtual std::shared_ptr vectorType(); + + public /* Built-in Types */: + static std::shared_ptr void_type; + static std::shared_ptr int_type; + static std::shared_ptr float_type; + static std::shared_ptr string_type; + static std::shared_ptr null_type; +}; + +class FuncType : public Type { + std::shared_ptr returnType; + std::shared_ptr params; + bool userlib; + bool cfunc; + + public: + FuncType(std::shared_ptr return_type, std::shared_ptr parameters, bool is_userlib, + bool is_customfunction); + virtual ~FuncType(); + + virtual std::shared_ptr funcType() override; +}; + +class ArrayType : public Type { + std::shared_ptr type; + int size; + + public: + ArrayType(std::shared_ptr type, int size); + virtual ~ArrayType(); + + virtual std::shared_ptr arrayType() override; +}; + +class StructType : public Type { + std::string ident; + std::shared_ptr fields; + + public: + StructType(const std::string& name); + StructType(const std::string& name, std::shared_ptr fields); + virtual ~StructType(); + + virtual std::shared_ptr structType() override; + + virtual bool canCastTo(std::shared_ptr t) override; +}; + +class ConstType : public Type { + std::shared_ptr 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() override; +}; + +class VectorType : public Type { + std::string label; + Type* elementType; + std::vector sizes; + + public: + VectorType(const std::string& l, Type* t, const std::vector& szs); + virtual ~VectorType(); + + virtual std::shared_ptr vectorType() override; + + virtual bool canCastTo(std::shared_ptr t) override; +}; diff --git a/compiler/var.hpp b/compiler/lib/var.hpp similarity index 74% rename from compiler/var.hpp rename to compiler/lib/var.hpp index 95133e5..01ede1c 100644 --- a/compiler/var.hpp +++ b/compiler/lib/var.hpp @@ -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 \ No newline at end of file diff --git a/compiler/varnode.cpp b/compiler/lib/varnode.cpp similarity index 83% rename from compiler/varnode.cpp rename to compiler/lib/varnode.cpp index 75266ce..5165f00 100644 --- a/compiler/varnode.cpp +++ b/compiler/lib/varnode.cpp @@ -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; +} diff --git a/compiler/varnode.hpp b/compiler/lib/varnode.hpp similarity index 57% rename from compiler/varnode.hpp rename to compiler/lib/varnode.hpp index 90df60c..ffe8c54 100644 --- a/compiler/varnode.hpp +++ b/compiler/lib/varnode.hpp @@ -1,8 +1,13 @@ +#pragma once +#include +#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; - Decl* sem_field; - FieldVarNode(ExprNode* e, const string& i, const string& t) : expr(e), ident(i), tag(t) {} - ~FieldVarNode() - { - delete expr; - } + ExprNode* expr; + std::string ident, tag; + Decl* sem_field; + 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 diff --git a/compiler/libs.cpp b/compiler/libs.cpp new file mode 100644 index 0000000..395f408 --- /dev/null +++ b/compiler/libs.cpp @@ -0,0 +1,381 @@ +#include "libs.hpp" +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +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 keyWords; +std::vector 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 _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; +} diff --git a/compiler/libs.hpp b/compiler/libs.hpp new file mode 100644 index 0000000..07ba69c --- /dev/null +++ b/compiler/libs.hpp @@ -0,0 +1,31 @@ +#pragma once +#include +#include + +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 keyWords; +extern std::vector userFuncs; + +const char* openLibs(); + +const char* linkLibs(); + +void closeLibs(); diff --git a/compiler/main.cpp b/compiler/main.cpp new file mode 100644 index 0000000..4b5d4c6 --- /dev/null +++ b/compiler/main.cpp @@ -0,0 +1,338 @@ + +#pragma warning(disable : 4786) + +#include "libs.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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::iterator it; + std::map& 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; + std::shared_ptr v_environ; + std::shared_ptr 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; + + 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; +} \ No newline at end of file diff --git a/compiler/node.hpp b/compiler/node.hpp deleted file mode 100644 index ab61bdb..0000000 --- a/compiler/node.hpp +++ /dev/null @@ -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 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 diff --git a/compiler/parser.hpp b/compiler/parser.hpp deleted file mode 100644 index ccdd003..0000000 --- a/compiler/parser.hpp +++ /dev/null @@ -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 included; - Toker * toker, *main_toker; - map 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 diff --git a/compiler/prognode.hpp b/compiler/prognode.hpp deleted file mode 100644 index b5b8df4..0000000 --- a/compiler/prognode.hpp +++ /dev/null @@ -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& userfuncs); -}; - -#endif \ No newline at end of file diff --git a/compiler/semant.old b/compiler/semant.old deleted file mode 100644 index d815a4b..0000000 --- a/compiler/semant.old +++ /dev/null @@ -1,53 +0,0 @@ - -#include "parser.h" - -void ExprSeqNode::semant( Scope *s ){ - - for( int k=0;ksemant( 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::iterator it; - for( it=s->idents.begin();it!=s->idents.end();++it ){ - if( LabelType *l=it->second->labelType() ){ - if( !l->defn ){ - semantEx( "Undefined Label" ); - } - } - } -} - diff --git a/compiler/std.cpp b/compiler/std.cpp deleted file mode 100644 index d5f561b..0000000 --- a/compiler/std.cpp +++ /dev/null @@ -1,2 +0,0 @@ - -#include "std.hpp" diff --git a/compiler/std.hpp b/compiler/std.hpp deleted file mode 100644 index 8a45e51..0000000 --- a/compiler/std.hpp +++ /dev/null @@ -1,21 +0,0 @@ - -#ifndef STD_COMPILER_H -#define STD_COMPILER_H - -#include "config.hpp" -#include "stdutil.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -#include - -#endif \ No newline at end of file diff --git a/compiler/stmtnode.hpp b/compiler/stmtnode.hpp deleted file mode 100644 index 192b3be..0000000 --- a/compiler/stmtnode.hpp +++ /dev/null @@ -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 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 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 diff --git a/compiler/stringmap.hpp b/compiler/stringmap.hpp deleted file mode 100644 index e69de29..0000000 diff --git a/compiler/stringmap.txt b/compiler/stringmap.txt deleted file mode 100644 index e69de29..0000000 diff --git a/compiler/syn.txt b/compiler/syn.txt deleted file mode 100644 index 8f81098..0000000 --- a/compiler/syn.txt +++ /dev/null @@ -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 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 &prog,Environ *e )=0; -}; - -struct StmtSeqNode : public Node{ - vector stmts; - public void semant( Environ *e ); - public void translate( vector &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 &prog,Environ *e )=0; -}; - -struct DeclSeqNode : public Node{ - vector decls; - public void proto( Environ *e ); - public void semant( Environ *e ); - public void translate( vector &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 &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 ); -}; diff --git a/compiler/type.cpp b/compiler/type.cpp deleted file mode 100644 index 6597cce..0000000 --- a/compiler/type.cpp +++ /dev/null @@ -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; diff --git a/compiler/type.hpp b/compiler/type.hpp deleted file mode 100644 index e00ceba..0000000 --- a/compiler/type.hpp +++ /dev/null @@ -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 sizes; - VectorType(const string& l, Type* t, const vector& szs) : label(l), elementType(t), sizes(szs) {} - VectorType* vectorType() - { - return this; - } - virtual bool canCastTo(Type* t); -}; - -#endif