ReactOS 0.4.15-dev-8419-g7f0e8a3
asmpp.cpp File Reference
#include "tokenizer.hpp"
#include <cstdlib>
#include <cstdio>
#include <sstream>
#include <ctime>
Include dependency graph for asmpp.cpp:

Go to the source code of this file.

Classes

struct  IDENTIFIER
 

Macros

#define PROFILING_ENABLED   0
 
#define FOLLOWED_BY(x)   x
 
#define ANY_CHAR   R"((?:.|\n))"
 
#define WHITESPACE   R"((?:[ \t]++))"
 
#define NEWLINE   R"([\n])"
 
#define WS_OR_NL   R"((?:)" WHITESPACE "|" NEWLINE R"()+)"
 
#define SEPARATOR   R"([\s,\=\+\-\*\/\:\~\[\]])"
 
#define INSTRUCTION
 

Enumerations

enum  TOKEN_TYPE {
  Invalid = -1 , Eof , WhiteSpace , NewLine ,
  Comment , DecNumber , HexNumber , String ,
  BraceOpen , BraceClose , MemRefStart , MemRefEnd ,
  Colon , Operator , StringDef , KW_include ,
  KW_const , KW_code , KW_endprolog , KW_ALIGN ,
  KW_EXTERN , KW_PUBLIC , KW_ENDM , KW_END ,
  KW_if , KW_ifdef , KW_ifndef , KW_else ,
  KW_endif , KW_allocstack , KW_savereg , KW_savexmm128 ,
  KW_DB , KW_DW , KW_DD , KW_DQ ,
  KW_EQU , KW_TEXTEQU , KW_MACRO , KW_PROC ,
  KW_FRAME , KW_ENDP , KW_RECORD , KW_MASK ,
  KW_ERRDEF , Filename , Instruction , Reg8 ,
  Reg16 , Reg32 , Reg64 , RegXmm ,
  BYTE_PTR , WORD_PTR , DWORD_PTR , QWORD_PTR ,
  XMMWORD_PTR , LabelName , Identifier
}
 
enum class  IDTYPE {
  Memory , Register , Label , Constant ,
  Macro , Instruction , String , Unknown
}
 

Functions

int fake_printf (const char *format,...)
 
static void add_identifier (Token &tok, IDTYPE type)
 
void add_mem_id (Token &tok)
 
bool is_mem_id (Token &tok)
 
bool iequals (const string &a, const string &b)
 
Token get_expected_token (Token &&tok, TOKEN_TYPE type)
 
Token get_ws (Token &&tok)
 
Token get_ws_or_nl (Token &&tok)
 
bool is_string_in_list (vector< string > list, string str)
 
size_t translate_token (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t complete_line (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t translate_expression (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t translate_mem_ref (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t translate_instruction_param (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
static bool is_jmp_or_call (const Token &tok)
 
size_t translate_instruction (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t translate_item (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t translate_list (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t translate_data_def (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t translate_construct_one_param (string translated, TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t translate_record (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t translate_identifier_construct (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t translate_construct (TokenList &tokens, size_t index, const vector< string > &macro_params)
 
size_t translate_macro (TokenList &tokens, size_t index)
 
void translate (TokenList &tokens)
 
int main (int argc, char *argv[])
 

Variables

time_t search_time
 
vector< TOKEN_DEFg_TokenList
 
unsigned int g_label_number = 0
 
bool g_processing_jmp = false
 
vector< IDENTIFIERg_identifiers
 

Macro Definition Documentation

◆ ANY_CHAR

#define ANY_CHAR   R"((?:.|\n))"

Definition at line 109 of file asmpp.cpp.

◆ FOLLOWED_BY

#define FOLLOWED_BY (   x)    x

Definition at line 107 of file asmpp.cpp.

◆ INSTRUCTION

#define INSTRUCTION

Definition at line 115 of file asmpp.cpp.

◆ NEWLINE

#define NEWLINE   R"([\n])"

Definition at line 111 of file asmpp.cpp.

◆ PROFILING_ENABLED

#define PROFILING_ENABLED   0

Definition at line 22 of file asmpp.cpp.

◆ SEPARATOR

#define SEPARATOR   R"([\s,\=\+\-\*\/\:\~\[\]])"

Definition at line 113 of file asmpp.cpp.

◆ WHITESPACE

#define WHITESPACE   R"((?:[ \t]++))"

Definition at line 110 of file asmpp.cpp.

◆ WS_OR_NL

#define WS_OR_NL   R"((?:)" WHITESPACE "|" NEWLINE R"()+)"

Definition at line 112 of file asmpp.cpp.

Enumeration Type Documentation

◆ IDTYPE

enum class IDTYPE
strong
Enumerator
Memory 
Register 
Label 
Constant 
Macro 
Instruction 
String 
Unknown 

Definition at line 301 of file asmpp.cpp.

302{
303 Memory,
304 Register,
305 Label,
306 Constant,
307 Macro,
309 String,
310 Unknown
311};
@ Instruction
Definition: asmpp.cpp:82
@ String
Definition: asmpp.cpp:37

◆ TOKEN_TYPE

Enumerator
Invalid 
Eof 
WhiteSpace 
NewLine 
Comment 
DecNumber 
HexNumber 
String 
BraceOpen 
BraceClose 
MemRefStart 
MemRefEnd 
Colon 
Operator 
StringDef 
KW_include 
KW_const 
KW_code 
KW_endprolog 
KW_ALIGN 
KW_EXTERN 
KW_PUBLIC 
KW_ENDM 
KW_END 
KW_if 
KW_ifdef 
KW_ifndef 
KW_else 
KW_endif 
KW_allocstack 
KW_savereg 
KW_savexmm128 
KW_DB 
KW_DW 
KW_DD 
KW_DQ 
KW_EQU 
KW_TEXTEQU 
KW_MACRO 
KW_PROC 
KW_FRAME 
KW_ENDP 
KW_RECORD 
KW_MASK 
KW_ERRDEF 
Filename 
Instruction 
Reg8 
Reg16 
Reg32 
Reg64 
RegXmm 
BYTE_PTR 
WORD_PTR 
DWORD_PTR 
QWORD_PTR 
XMMWORD_PTR 
LabelName 
Identifier 

Definition at line 28 of file asmpp.cpp.

29{
30 Invalid = -1,
31 Eof,
33 NewLine,
34 Comment,
37 String,
38
43 Colon,
46
49 KW_code,
54 KW_ENDM,
55 KW_END,
56 KW_if,
59 KW_else,
61
65
66 KW_DB,
67 KW_DW,
68 KW_DD,
69 KW_DQ,
70 KW_EQU,
73 KW_PROC,
75 KW_ENDP,
77
78 KW_MASK,
80
83 Reg8,
84 Reg16,
85 Reg32,
86 Reg64,
87 RegXmm,
93
96};
@ KW_allocstack
Definition: asmpp.cpp:62
@ Reg32
Definition: asmpp.cpp:85
@ KW_FRAME
Definition: asmpp.cpp:74
@ KW_savereg
Definition: asmpp.cpp:63
@ KW_EXTERN
Definition: asmpp.cpp:52
@ KW_PROC
Definition: asmpp.cpp:73
@ StringDef
Definition: asmpp.cpp:45
@ MemRefEnd
Definition: asmpp.cpp:42
@ KW_ENDM
Definition: asmpp.cpp:54
@ BraceClose
Definition: asmpp.cpp:40
@ Comment
Definition: asmpp.cpp:34
@ KW_else
Definition: asmpp.cpp:59
@ KW_END
Definition: asmpp.cpp:55
@ KW_code
Definition: asmpp.cpp:49
@ KW_endprolog
Definition: asmpp.cpp:50
@ DecNumber
Definition: asmpp.cpp:35
@ Identifier
Definition: asmpp.cpp:95
@ KW_DW
Definition: asmpp.cpp:67
@ BraceOpen
Definition: asmpp.cpp:39
@ KW_RECORD
Definition: asmpp.cpp:76
@ Colon
Definition: asmpp.cpp:43
@ KW_ENDP
Definition: asmpp.cpp:75
@ Filename
Definition: asmpp.cpp:81
@ KW_EQU
Definition: asmpp.cpp:70
@ BYTE_PTR
Definition: asmpp.cpp:88
@ RegXmm
Definition: asmpp.cpp:87
@ WhiteSpace
Definition: asmpp.cpp:32
@ KW_DB
Definition: asmpp.cpp:66
@ MemRefStart
Definition: asmpp.cpp:41
@ QWORD_PTR
Definition: asmpp.cpp:91
@ KW_include
Definition: asmpp.cpp:47
@ KW_MACRO
Definition: asmpp.cpp:72
@ HexNumber
Definition: asmpp.cpp:36
@ KW_DD
Definition: asmpp.cpp:68
@ LabelName
Definition: asmpp.cpp:94
@ KW_const
Definition: asmpp.cpp:48
@ KW_TEXTEQU
Definition: asmpp.cpp:71
@ Reg8
Definition: asmpp.cpp:83
@ NewLine
Definition: asmpp.cpp:33
@ KW_ifndef
Definition: asmpp.cpp:58
@ KW_ifdef
Definition: asmpp.cpp:57
@ XMMWORD_PTR
Definition: asmpp.cpp:92
@ KW_PUBLIC
Definition: asmpp.cpp:53
@ Operator
Definition: asmpp.cpp:44
@ KW_DQ
Definition: asmpp.cpp:69
@ Eof
Definition: asmpp.cpp:31
@ KW_ALIGN
Definition: asmpp.cpp:51
@ KW_savexmm128
Definition: asmpp.cpp:64
@ DWORD_PTR
Definition: asmpp.cpp:90
@ KW_endif
Definition: asmpp.cpp:60
@ KW_MASK
Definition: asmpp.cpp:78
@ KW_if
Definition: asmpp.cpp:56
@ WORD_PTR
Definition: asmpp.cpp:89
@ Invalid
Definition: asmpp.cpp:30
@ Reg16
Definition: asmpp.cpp:84
@ Reg64
Definition: asmpp.cpp:86
@ KW_ERRDEF
Definition: asmpp.cpp:79

Function Documentation

◆ add_identifier()

static void add_identifier ( Token tok,
IDTYPE  type 
)
static

Definition at line 323 of file asmpp.cpp.

324{
325 g_identifiers.push_back(IDENTIFIER{ tok.str(), type });
326 //fprintf(stderr, "Added id: '%s'\n", tok.str().c_str());
327}
vector< IDENTIFIER > g_identifiers
Definition: asmpp.cpp:319
std::string str() const
Definition: tokenizer.hpp:50
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545

Referenced by add_mem_id(), and translate_identifier_construct().

◆ add_mem_id()

void add_mem_id ( Token tok)

Definition at line 330 of file asmpp.cpp.

331{
333}
static void add_identifier(Token &tok, IDTYPE type)
Definition: asmpp.cpp:323

Referenced by translate_construct(), and translate_identifier_construct().

◆ complete_line()

size_t complete_line ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 469 of file asmpp.cpp.

470{
471 while (index < tokens.size())
472 {
473 Token tok = tokens[index];
474 index = translate_token(tokens, index, macro_params);
475 if ((tok.type() == TOKEN_TYPE::NewLine) ||
476 (tok.type() == TOKEN_TYPE::Comment))
477 {
478 break;
479 }
480 }
481
482 return index;
483}
size_t translate_token(TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:409
#define index(s, c)
Definition: various.h:29
size_t size() const
Definition: tokenizer.hpp:239
int type() const
Definition: tokenizer.hpp:55
GLuint index
Definition: glext.h:6031

Referenced by translate_construct().

◆ fake_printf()

int fake_printf ( const char format,
  ... 
)

Definition at line 98 of file asmpp.cpp.

99{
100 return 0;
101}

◆ get_expected_token()

Token get_expected_token ( Token &&  tok,
TOKEN_TYPE  type 
)

Definition at line 362 of file asmpp.cpp.

363{
364 if (tok.type() != type)
365 {
366 throw "Not white space after identifier!\n";
367 }
368
369 return tok;
370}

Referenced by translate_construct(), translate_identifier_construct(), and translate_record().

◆ get_ws()

Token get_ws ( Token &&  tok)

Definition at line 372 of file asmpp.cpp.

373{
374 int type = tok.type();
375 if (type != TOKEN_TYPE::WhiteSpace)
376 {
377 throw "Not white space after identifier!\n";
378 }
379
380 return tok;
381}

Referenced by translate_construct_one_param(), translate_data_def(), and translate_identifier_construct().

◆ get_ws_or_nl()

Token get_ws_or_nl ( Token &&  tok)

Definition at line 383 of file asmpp.cpp.

384{
385 int type = tok.type();
386 if ((type != TOKEN_TYPE::WhiteSpace) &&
387 (type != TOKEN_TYPE::NewLine))
388 {
389 throw "Not white space after identifier!\n";
390 }
391
392 return tok;
393}

Referenced by translate_construct().

◆ iequals()

bool iequals ( const string a,
const string b 
)

Definition at line 350 of file asmpp.cpp.

351{
352 size_t sz = a.size();
353 if (b.size() != sz)
354 return false;
355 for (unsigned int i = 0; i < sz; ++i)
356 if (tolower(a[i]) != tolower(b[i]))
357 return false;
358 return true;
359}
int tolower(int c)
Definition: utclib.c:902
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248

Referenced by is_jmp_or_call(), and translate_expression().

◆ is_jmp_or_call()

static bool is_jmp_or_call ( const Token tok)
static

Definition at line 639 of file asmpp.cpp.

640{
641 const char* inst_list[] = {
642 "jmp", "call", "ja", "jae", "jb", "jbe", "jc", "jcxz", "je", "jecxz", "jg", "jge",
643 "jl", "jle", "jna", "jnae", "jnb", "jnbe", "jnc", "jne", "jng", "jnge", "jnl", "jnle",
644 "jno", "jnp", "jns", "jnz", "jo", "jp", "jpe", "jpo", "jrcxz", "js", "jz", "loop", "loope",
645 "loopne", "loopnz", "loopz"
646 };
647
648 for (const char* inst : inst_list)
649 {
650 if (iequals(tok.str(), inst))
651 {
652 return true;
653 }
654 }
655
656 return false;
657}
bool iequals(const string &a, const string &b)
Definition: asmpp.cpp:350

Referenced by translate_instruction().

◆ is_mem_id()

bool is_mem_id ( Token tok)

Definition at line 336 of file asmpp.cpp.

337{
338 for (IDENTIFIER& identifier : g_identifiers)
339 {
340 if (identifier.Name == tok.str())
341 {
342 return identifier.Type == IDTYPE::Memory;
343 }
344 }
345
346 return true;
347}

Referenced by translate_instruction_param().

◆ is_string_in_list()

bool is_string_in_list ( vector< string list,
string  str 
)

Definition at line 395 of file asmpp.cpp.

396{
397 for (string &s : list)
398 {
399 if (s == str)
400 {
401 return true;
402 }
403 }
404
405 return false;
406}
Definition: list.h:37
GLdouble s
Definition: gl.h:2039
const WCHAR * str

Referenced by translate_instruction_param(), and translate_token().

◆ main()

int main ( int argc  ,
char argv[] 
)

Definition at line 1228 of file asmpp.cpp.

1229{
1230 if (argc < 2)
1231 {
1232 fprintf(stderr, "Invalid parameter!\n");
1233 return -1;
1234 }
1235
1236#if PROFILING_ENABLED
1237 time_t start_time = time(NULL);
1238#endif
1239
1240 try
1241 {
1242 // Open and read the input file
1243 string filename(argv[1]);
1246 buffer << file.rdbuf();
1247 string text = buffer.str();
1248
1249 // Create the tokenizer
1250 Tokenizer tokenizer(g_TokenList);
1251
1252 // Get a token list
1253 TokenList toklist(tokenizer, text);
1254
1255 // Now translate the tokens
1256 translate(toklist);
1257 }
1258 catch (const char* message)
1259 {
1260 fprintf(stderr, "Exception caught: '%s'\n", message);
1261 return -2;
1262 }
1263
1264#if PROFILING_ENABLED
1265 time_t total_time = time(NULL) + 1 - start_time;
1266 fprintf(stderr, "total_time = %llu\n", total_time);
1267 fprintf(stderr, "search_time = %llu\n", search_time);
1268 fprintf(stderr, "search: %llu %%\n", search_time * 100 / total_time);
1269#endif
1270
1271 return 0;
1272}
static int argc
Definition: ServiceArgs.c:12
vector< TOKEN_DEF > g_TokenList
Definition: asmpp.cpp:225
void translate(TokenList &tokens)
Definition: asmpp.cpp:1206
time_t search_time
Definition: asmpp.cpp:26
#define NULL
Definition: types.h:112
const WCHAR * text
Definition: package.c:1799
__kernel_time_t time_t
Definition: linux.h:252
GLuint buffer
Definition: glext.h:5915
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
const char * filename
Definition: ioapi.h:137
__u16 time
Definition: mkdosfs.c:8
#define argv
Definition: mplay32.c:18
Definition: fci.c:127
Definition: tftpd.h:60

◆ translate()

void translate ( TokenList tokens)

Definition at line 1206 of file asmpp.cpp.

1207{
1208 size_t index = 0;
1209 size_t size = tokens.size();
1210 vector<string> empty_macro_params;
1211
1212 while (index < size)
1213 {
1214 // Macros are special
1215 if ((tokens[index].type() == TOKEN_TYPE::Identifier) &&
1216 (tokens[index + 1].type() == TOKEN_TYPE::WhiteSpace) &&
1217 (tokens[index + 2].type() == TOKEN_TYPE::KW_MACRO))
1218 {
1219 index = translate_macro(tokens, index);
1220 }
1221 else
1222 {
1223 index = translate_construct(tokens, index, empty_macro_params);
1224 }
1225 }
1226}
size_t translate_construct(TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:1031
size_t translate_macro(TokenList &tokens, size_t index)
Definition: asmpp.cpp:1153
GLsizeiptr size
Definition: glext.h:5919

Referenced by main().

◆ translate_construct()

size_t translate_construct ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 1031 of file asmpp.cpp.

1032{
1033 Token tok = tokens[index];
1034
1035 switch (tok.type())
1036 {
1037 case TOKEN_TYPE::WhiteSpace:
1038 case TOKEN_TYPE::NewLine:
1039 case TOKEN_TYPE::Comment:
1040 return translate_token(tokens, index, macro_params);
1041
1042 case TOKEN_TYPE::Identifier:
1043 return translate_identifier_construct(tokens, index, macro_params);
1044
1045 case TOKEN_TYPE::KW_ALIGN:
1046 index = translate_construct_one_param(".align", tokens, index, macro_params);
1047 break;
1048
1049 case TOKEN_TYPE::KW_allocstack:
1050 index = translate_construct_one_param(".seh_stackalloc", tokens, index, macro_params);
1051 break;
1052
1053 case TOKEN_TYPE::KW_code:
1054#ifdef TARGET_amd64
1055 printf(".code64");
1056#else
1057 printf(".code");
1058#endif
1059 printf(" .intel_syntax noprefix");
1060 index++;
1061 break;
1062
1063 case TOKEN_TYPE::KW_const:
1064 printf(".section .rdata");
1065 index++;
1066 break;
1067
1068 case TOKEN_TYPE::KW_DB:
1069 case TOKEN_TYPE::KW_DW:
1070 case TOKEN_TYPE::KW_DD:
1071 case TOKEN_TYPE::KW_DQ:
1072 return translate_data_def(tokens, index, macro_params);
1073
1074 case TOKEN_TYPE::KW_END:
1075 printf("// END\n");
1076 return tokens.size();
1077
1078 case TOKEN_TYPE::KW_endprolog:
1079 printf(".seh_endprologue");
1080 index++;
1081 break;
1082
1083 case TOKEN_TYPE::KW_EXTERN:
1084 {
1085 Token tok1 = get_ws_or_nl(tokens[index + 1]);
1086 Token tok2 = get_expected_token(tokens[index + 2], TOKEN_TYPE::Identifier);
1087 add_mem_id(tok2);
1088 printf("//");
1089 return complete_line(tokens, index, macro_params);
1090 }
1091
1092 case TOKEN_TYPE::KW_if:
1093 case TOKEN_TYPE::KW_ifdef:
1094 case TOKEN_TYPE::KW_ifndef:
1095 case TOKEN_TYPE::KW_else:
1096 case TOKEN_TYPE::KW_endif:
1097 // TODO: handle parameter differences between "if" and ".if" etc.
1098 printf(".");
1099 return complete_line(tokens, index, macro_params);
1100
1101 case TOKEN_TYPE::KW_include:
1102 {
1103 // The next token should be white space
1104 Token tok1 = get_ws_or_nl(tokens[index + 1]);
1105 Token tok2 = get_expected_token(tokens[index + 2], TOKEN_TYPE::Filename);
1106 printf("#include \"%s.h\"", tok2.str().c_str());
1107 index += 3;
1108 break;
1109 }
1110
1111 case TOKEN_TYPE::KW_PUBLIC:
1112 index = translate_construct_one_param(".global", tokens, index, macro_params);
1113 break;
1114
1115 case TOKEN_TYPE::KW_savereg:
1116 printf(".seh_savereg");
1117 return complete_line(tokens, index + 1, macro_params);
1118
1119 case TOKEN_TYPE::KW_savexmm128:
1120 printf(".seh_savexmm");
1121 return complete_line(tokens, index + 1, macro_params);
1122
1123 case TOKEN_TYPE::Instruction:
1124 index = translate_instruction(tokens, index, macro_params);
1125 break;
1126
1127 case TOKEN_TYPE::KW_ERRDEF:
1128 printf("//");
1129 return complete_line(tokens, index, macro_params);
1130
1131 default:
1132 throw "failed to translate construct";
1133 }
1134
1135 // Skip optional white-space
1136 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
1137 {
1138 index++;
1139 }
1140
1141 // Line should end here!
1142 Token end = tokens[index];
1143 if ((end.type() != TOKEN_TYPE::Comment) &&
1144 (end.type() != TOKEN_TYPE::NewLine))
1145 {
1146 throw "unexpected tokens";
1147 }
1148
1149 return index;
1150}
void add_mem_id(Token &tok)
Definition: asmpp.cpp:330
size_t translate_data_def(TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:757
Token get_ws_or_nl(Token &&tok)
Definition: asmpp.cpp:383
size_t complete_line(TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:469
Token get_expected_token(Token &&tok, TOKEN_TYPE type)
Definition: asmpp.cpp:362
size_t translate_identifier_construct(TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:938
size_t translate_construct_one_param(string translated, TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:848
size_t translate_instruction(TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:659
#define printf
Definition: freeldr.h:97
GLuint GLuint end
Definition: gl.h:1545

Referenced by translate(), and translate_macro().

◆ translate_construct_one_param()

size_t translate_construct_one_param ( string  translated,
TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 848 of file asmpp.cpp.

849{
850 // The next token should be white space
851 Token tok1 = get_ws(tokens[index + 1]);
852
853 printf("%s%s", translated.c_str(), tok1.str().c_str());
854 return translate_expression(tokens, index + 2, macro_params);
855}
size_t translate_expression(TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:486
Token get_ws(Token &&tok)
Definition: asmpp.cpp:372
const _CharT * c_str() const
Definition: _string.h:949

Referenced by translate_construct().

◆ translate_data_def()

size_t translate_data_def ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 757 of file asmpp.cpp.

758{
759 Token tok = tokens[index];
760 Token tok1 = get_ws(tokens[index + 1]);
761 string directive, need, have ="";
762
763 switch (tok.type())
764 {
765 case TOKEN_TYPE::KW_DB:
766 directive = ".byte";
767 break;
768
769 case TOKEN_TYPE::KW_DW:
770 directive = ".short";
771 break;
772
773 case TOKEN_TYPE::KW_DD:
774 directive = ".long";
775 break;
776
777 case TOKEN_TYPE::KW_DQ:
778 directive = ".quad";
779 break;
780 }
781
782 index += 2;
783
784 while (index < tokens.size())
785 {
786 // Check if we need '.ascii' for ASCII strings
787 if (tokens[index].str()[0] == '\"')
788 {
789 need = ".ascii";
790 }
791 else
792 {
793 need = directive;
794 }
795
796 // Output the directive we need (or a comma)
797 if (have == "")
798 {
799 printf("%s ", need.c_str());
800 }
801 else if (have != need)
802 {
803 printf("\n%s ", need.c_str());
804 }
805 else
806 {
807 printf(", ");
808 }
809
810 have = need;
811
812 // The item itself
813 index = translate_item(tokens, index, macro_params);
814
815 // Optional white space
816 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
817 {
818 index = translate_token(tokens, index, macro_params);
819 }
820
821 // End of list?
822 if ((tokens[index].type() == TOKEN_TYPE::Comment) ||
823 (tokens[index].type() == TOKEN_TYPE::NewLine))
824 {
825 return index;
826 }
827
828 // We expect a comma here
829 if ((tokens[index].type() != TOKEN_TYPE::Operator) ||
830 (tokens[index].str() != ","))
831 {
832 throw "Unexpected end of list";
833 }
834
835 // Skip comma and optional white-space
836 index++;
837 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
838 {
839 index++;
840 }
841 }
842
843 throw "Failed to translate list";
844 return -1;
845}
size_t translate_item(TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:703
static UINT PSTR DWORD UINT * need
Definition: parser.c:36

Referenced by translate_construct(), and translate_identifier_construct().

◆ translate_expression()

size_t translate_expression ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 486 of file asmpp.cpp.

487{
488 while (index < tokens.size())
489 {
490 Token tok = tokens[index];
491 switch (tok.type())
492 {
493 case TOKEN_TYPE::NewLine:
494 case TOKEN_TYPE::Comment:
495 return index;
496
497 case TOKEN_TYPE::KW_MASK:
498 printf("MASK_");
499 index += 2;
500 break;
501
502 case TOKEN_TYPE::Instruction:
503 if (iequals(tok.str(), "and"))
504 {
505 printf("&");
506 index += 1;
507 }
508 else if (iequals(tok.str(), "or"))
509 {
510 printf("|");
511 index += 1;
512 }
513 else if (iequals(tok.str(), "shl"))
514 {
515 printf("<<");
516 index += 1;
517 }
518 else if (iequals(tok.str(), "not"))
519 {
520 printf("!");
521 index += 1;
522 }
523 else
524 {
525 throw "Invalid expression";
526 }
527 break;
528
529 case TOKEN_TYPE::Operator:
530 if (tok.str() == ",")
531 {
532 return index;
533 }
534 case TOKEN_TYPE::WhiteSpace:
535 case TOKEN_TYPE::BraceOpen:
536 case TOKEN_TYPE::BraceClose:
537 case TOKEN_TYPE::DecNumber:
538 case TOKEN_TYPE::HexNumber:
539 case TOKEN_TYPE::Identifier:
540 index = translate_token(tokens, index, macro_params);
541 break;
542
543 default:
544 index = translate_token(tokens, index, macro_params);
545 }
546 }
547
548 return index;
549}

Referenced by translate_construct_one_param(), translate_identifier_construct(), and translate_instruction_param().

◆ translate_identifier_construct()

size_t translate_identifier_construct ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 938 of file asmpp.cpp.

939{
940 Token tok = tokens[index];
941 Token tok1 = tokens[index + 1];
942
943 if (tok1.type() == TOKEN_TYPE::Colon)
944 {
945 if (tok.str() == "@@")
946 {
948 printf("%u:", g_label_number);
949 }
950 else
951 {
952 printf("%s:", tok.str().c_str());
953 }
955 return index + 2;
956 }
957
958 Token tok2 = tokens[index + 2];
959
960 switch (tok2.type())
961 {
962 case TOKEN_TYPE::KW_MACRO:
963 throw "Cannot have a nested macro!";
964
965 case TOKEN_TYPE::KW_DB:
966 case TOKEN_TYPE::KW_DW:
967 case TOKEN_TYPE::KW_DD:
968 case TOKEN_TYPE::KW_DQ:
969 printf("%s:%s", tok.str().c_str(), tok1.str().c_str());
970 add_mem_id(tok);
971 return translate_data_def(tokens, index + 2, macro_params);
972
973 case TOKEN_TYPE::KW_EQU:
974 //printf("%s%s", tok.str().c_str(), tok1.str().c_str());
975 printf("#define %s ", tok.str().c_str());
977 return translate_expression(tokens, index + 3, macro_params);
978
979 case TOKEN_TYPE::KW_TEXTEQU:
980 {
981 Token tok3 = get_ws(tokens[index + 3]);
982 Token tok4 = get_expected_token(tokens[index + 4], TOKEN_TYPE::StringDef);
983
984 string textdef = tok4.str();
985 printf("#define %s %s", tok.str().c_str(), textdef.substr(1, textdef.size() - 2).c_str());
987 return index + 5;
988 }
989
990 case TOKEN_TYPE::KW_PROC:
991 {
992 printf(".func %s\n", tok.str().c_str());
993 printf("%s:", tok.str().c_str());
994 index += 3;
995
996 if ((tokens[index].type() == TOKEN_TYPE::WhiteSpace) &&
997 (tokens[index + 1].type() == TOKEN_TYPE::KW_FRAME))
998 {
999#ifdef TARGET_amd64
1000 printf("\n.seh_proc %s\n", tok.str().c_str());
1001#else
1002 printf("\n.cfi_startproc\n");
1003#endif
1004 index += 2;
1005 }
1007 break;
1008 }
1009
1010 case TOKEN_TYPE::KW_ENDP:
1011 {
1012 printf(".seh_endproc\n.endfunc");
1013 index += 3;
1014 break;
1015 }
1016
1017 case TOKEN_TYPE::KW_RECORD:
1018 index = translate_record(tokens, index, macro_params);
1019 break;
1020
1021 default:
1022 // We don't know what it is, assume it's a macro and treat it like an instruction
1023 index = translate_instruction(tokens, index, macro_params);
1024 break;
1025 }
1026
1027 return index;
1028}
unsigned int g_label_number
Definition: asmpp.cpp:297
size_t translate_record(TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:858
_Self substr(size_type __pos=0, size_type __n=npos) const
Definition: _string.h:1022
size_type size() const
Definition: _string.h:400

Referenced by translate_construct().

◆ translate_instruction()

size_t translate_instruction ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 659 of file asmpp.cpp.

660{
661 // Check for jump/call instructions
662 if (is_jmp_or_call(tokens[index]))
663 {
664 g_processing_jmp = true;
665 }
666
667 // Translate the instruction itself
668 index = translate_token(tokens, index, macro_params);
669
670 // Handle instruction parameters
671 while (index < tokens.size())
672 {
673 // Optional whitespace
674 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
675 {
676 index = translate_token(tokens, index, macro_params);
677 }
678
679 // Check for parameters
680 Token tok = tokens[index];
681 switch (tok.type())
682 {
683 case TOKEN_TYPE::Comment:
684 case TOKEN_TYPE::NewLine:
685 g_processing_jmp = false;
686 return index;
687
688 case TOKEN_TYPE::WhiteSpace:
689 case TOKEN_TYPE::Operator:
690 index = translate_token(tokens, index, macro_params);
691 break;
692
693 default:
694 index = translate_instruction_param(tokens, index, macro_params);
695 break;
696 }
697 }
698
699 g_processing_jmp = false;
700 return index;
701}
static bool is_jmp_or_call(const Token &tok)
Definition: asmpp.cpp:639
bool g_processing_jmp
Definition: asmpp.cpp:299
size_t translate_instruction_param(TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:584

Referenced by translate_construct(), and translate_identifier_construct().

◆ translate_instruction_param()

size_t translate_instruction_param ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 584 of file asmpp.cpp.

585{
586 switch (tokens[index].type())
587 {
588 case TOKEN_TYPE::BYTE_PTR:
589 case TOKEN_TYPE::WORD_PTR:
590 case TOKEN_TYPE::DWORD_PTR:
591 case TOKEN_TYPE::QWORD_PTR:
592 case TOKEN_TYPE::XMMWORD_PTR:
593 index = translate_token(tokens, index, macro_params);
594
595 // Optional whitespace
596 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
597 {
598 index = translate_token(tokens, index, macro_params);
599 }
600 }
601
602 while (index < tokens.size())
603 {
604 Token tok = tokens[index];
605 switch (tok.type())
606 {
607 case TOKEN_TYPE::MemRefStart:
608 return translate_mem_ref(tokens, index, macro_params);
609
610 case TOKEN_TYPE::NewLine:
611 case TOKEN_TYPE::Comment:
612 return index;
613
614 case TOKEN_TYPE::Operator:
615 if (tok.str() == ",")
616 return index;
617 return translate_token(tokens, index, macro_params);
618
619 case TOKEN_TYPE::Identifier:
620 index = translate_token(tokens, index, macro_params);
621 if (is_mem_id(tok) &&
622 !is_string_in_list(macro_params, tok.str()) &&
624 {
625 printf("[rip]");
626 }
627 break;
628
629 default:
630 index = translate_expression(tokens, index, macro_params);
631 }
632 }
633
634 return index;
635}
bool is_mem_id(Token &tok)
Definition: asmpp.cpp:336
bool is_string_in_list(vector< string > list, string str)
Definition: asmpp.cpp:395
size_t translate_mem_ref(TokenList &tokens, size_t index, const vector< string > &macro_params)
Definition: asmpp.cpp:551

Referenced by translate_instruction().

◆ translate_item()

size_t translate_item ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 703 of file asmpp.cpp.

704{
705 switch (tokens[index].type())
706 {
707 case TOKEN_TYPE::DecNumber:
708 case TOKEN_TYPE::HexNumber:
709 case TOKEN_TYPE::String:
710 case TOKEN_TYPE::WhiteSpace:
711 return translate_token(tokens, index, macro_params);
712 }
713
714 throw "Failed to translate item";
715 return -1;
716}

Referenced by translate_data_def(), and translate_list().

◆ translate_list()

size_t translate_list ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 718 of file asmpp.cpp.

719{
720 while (index < tokens.size())
721 {
722 // The item itself
723 index = translate_item(tokens, index, macro_params);
724
725 // Optional white space
726 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
727 {
728 index = translate_token(tokens, index, macro_params);
729 }
730
731 // End of list?
732 if ((tokens[index].type() == TOKEN_TYPE::Comment) ||
733 (tokens[index].type() == TOKEN_TYPE::NewLine))
734 {
735 return index;
736 }
737
738 // We expect a comma here
739 if ((tokens[index].type() != TOKEN_TYPE::Operator) ||
740 (tokens[index].str() != ","))
741 {
742 throw "Unexpected end of list";
743 }
744
745 index = translate_token(tokens, index, macro_params);
746 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
747 {
748 index = translate_token(tokens, index, macro_params);
749 }
750 }
751
752 throw "Failed to translate list";
753 return -1;
754}

◆ translate_macro()

size_t translate_macro ( TokenList tokens,
size_t  index 
)

Definition at line 1153 of file asmpp.cpp.

1154{
1155 vector<string> macro_params;
1156
1157 printf(".macro %s", tokens[index].str().c_str());
1158
1159 // Parse marameters
1160 index += 3;
1161 while (index < tokens.size())
1162 {
1163 Token tok = tokens[index];
1164 switch (tok.type())
1165 {
1166 case TOKEN_TYPE::NewLine:
1167 case TOKEN_TYPE::Comment:
1168 index = translate_token(tokens, index, macro_params);
1169 break;
1170
1171 case TOKEN_TYPE::Identifier:
1172 macro_params.push_back(tok.str());
1173 printf("%s", tok.str().c_str());
1174 index++;
1175 continue;
1176
1177 case TOKEN_TYPE::WhiteSpace:
1178 case TOKEN_TYPE::Operator:
1179 index = translate_token(tokens, index, macro_params);
1180 continue;
1181 }
1182
1183 break;
1184 }
1185
1186 // Parse content
1187 while (index < tokens.size())
1188 {
1189 Token tok = tokens[index];
1190 switch (tok.type())
1191 {
1192 case TOKEN_TYPE::KW_ENDM:
1193 printf(".endm");
1194 return index + 1;
1195
1196 default:
1197 index = translate_construct(tokens, index, macro_params);
1198 }
1199 }
1200
1201 throw "Failed to translate macro";
1202 return -1;
1203}
void push_back(const _Tp &__x=_STLP_DEFAULT_CONSTRUCTED(_Tp))
Definition: _vector.h:379

Referenced by translate().

◆ translate_mem_ref()

size_t translate_mem_ref ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 551 of file asmpp.cpp.

552{
553 unsigned int offset = 0;
554
555 Token tok = tokens[index];
556
557 if ((tok.type() == TOKEN_TYPE::DecNumber) ||
558 (tok.type() == TOKEN_TYPE::HexNumber))
559 {
560 offset = stoi(tok.str(), nullptr, 0);
561 index += 2;
562 }
563
564 index = translate_token(tokens, index, macro_params);
565
566 while (index < tokens.size())
567 {
568 Token tok = tokens[index];
569 index = translate_token(tokens, index, macro_params);
570 if (tok.type() == TOKEN_TYPE::MemRefEnd)
571 {
572 if (offset != 0)
573 {
574 printf(" + %u", offset);
575 }
576 return index;
577 }
578 }
579
580 throw "Failed to translate memory ref";
581 return index;
582}
GLintptr offset
Definition: glext.h:5920

Referenced by translate_instruction_param().

◆ translate_record()

size_t translate_record ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 858 of file asmpp.cpp.

859{
860 unsigned int bits, bitpos = 0;
861 unsigned long long oldmask = 0, mask = 0;
862
863 Token tok_name = get_expected_token(tokens[index], TOKEN_TYPE::Identifier);
864 index += 4;
865 while (index < tokens.size())
866 {
867 Token tok_member = get_expected_token(tokens[index++], TOKEN_TYPE::Identifier);
868
869 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
870 {
871 index++;
872 }
873
874 if (tokens[index++].str() != ":")
875 {
876 throw "Unexpected token";
877 }
878
879 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
880 {
881 index++;
882 }
883
884 Token tok_bits = tokens[index++];
885 if ((tok_bits.type() != TOKEN_TYPE::DecNumber) &&
886 (tok_bits.type() != TOKEN_TYPE::HexNumber))
887 {
888 throw "Unexpected token";
889 }
890
891 bits = stoi(tok_bits.str(), nullptr, 0);
892
893 printf("%s = %u\n", tok_member.str().c_str(), bitpos);
894
895 oldmask = (1ULL << bitpos) - 1;
896 bitpos += bits;
897 mask = (1ULL << bitpos) - 1 - oldmask;
898 printf("MASK_%s = 0x%llx\n", tok_member.str().c_str(), mask);
899
900 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
901 {
902 index++;
903 }
904
905 if ((tokens[index].type() == TOKEN_TYPE::NewLine) ||
906 (tokens[index].type() == TOKEN_TYPE::Comment))
907 {
908 break;
909 }
910
911 if (tokens[index].str() != ",")
912 {
913 throw "unexpected token";
914 }
915
916 index++;
917 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
918 {
919 index++;
920 }
921
922 if ((tokens[index].type() == TOKEN_TYPE::NewLine) ||
923 (tokens[index].type() == TOKEN_TYPE::Comment))
924 {
925 index++;
926 }
927
928 if (tokens[index].type() == TOKEN_TYPE::WhiteSpace)
929 {
930 index++;
931 }
932 }
933
934 return index;
935}
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
#define bits
Definition: infblock.c:15

Referenced by translate_identifier_construct().

◆ translate_token()

size_t translate_token ( TokenList tokens,
size_t  index,
const vector< string > &  macro_params 
)

Definition at line 409 of file asmpp.cpp.

410{
411 Token tok = tokens[index];
412 switch (tok.type())
413 {
414 case TOKEN_TYPE::Comment:
415 printf("//%s", tok.str().c_str() + 1);
416 break;
417
418 case TOKEN_TYPE::DecNumber:
419 {
420 unsigned long long num = stoull(tok.str(), nullptr, 10);
421 printf("%llu", num);
422 break;
423 }
424
425 case TOKEN_TYPE::HexNumber:
426 {
427 string number = tok.str();
428 printf("0x%s", number.substr(0, number.size() - 1).c_str());
429 break;
430 }
431
432 case TOKEN_TYPE::Identifier:
433 if (is_string_in_list(macro_params, tok.str()))
434 {
435 printf("\\");
436 }
437 printf("%s", tok.str().c_str());
438 break;
439
440 // We migt want to improve these
441 case TOKEN_TYPE::BYTE_PTR:
442 case TOKEN_TYPE::WORD_PTR:
443 case TOKEN_TYPE::DWORD_PTR:
444 case TOKEN_TYPE::QWORD_PTR:
445 case TOKEN_TYPE::XMMWORD_PTR:
446
447 // Check these. valid only in instructions?
448 case TOKEN_TYPE::Reg8:
449 case TOKEN_TYPE::Reg16:
450 case TOKEN_TYPE::Reg32:
451 case TOKEN_TYPE::Reg64:
452 case TOKEN_TYPE::RegXmm:
453 case TOKEN_TYPE::Instruction:
454
455 case TOKEN_TYPE::WhiteSpace:
456 case TOKEN_TYPE::NewLine:
457 case TOKEN_TYPE::Operator:
458 printf("%s", tok.str().c_str());
459 break;
460
461 default:
462 printf("%s", tok.str().c_str());
463 break;
464 }
465
466 return index + 1;
467}
GLuint GLuint num
Definition: glext.h:9618
static unsigned int number
Definition: dsound.c:1479

Referenced by complete_line(), translate_construct(), translate_data_def(), translate_expression(), translate_instruction(), translate_instruction_param(), translate_item(), translate_list(), translate_macro(), and translate_mem_ref().

Variable Documentation

◆ g_identifiers

vector<IDENTIFIER> g_identifiers

Definition at line 319 of file asmpp.cpp.

Referenced by add_identifier(), and is_mem_id().

◆ g_label_number

unsigned int g_label_number = 0

Definition at line 297 of file asmpp.cpp.

Referenced by translate_identifier_construct().

◆ g_processing_jmp

bool g_processing_jmp = false

Definition at line 299 of file asmpp.cpp.

Referenced by translate_instruction(), and translate_instruction_param().

◆ g_TokenList

vector<TOKEN_DEF> g_TokenList

Definition at line 225 of file asmpp.cpp.

Referenced by main().

◆ search_time

time_t search_time

Definition at line 26 of file asmpp.cpp.

Referenced by main(), and Tokenizer::match().