加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
compile.c 10.42 KB
一键复制 编辑 原始数据 按行查看 历史
林博珩 提交于 2021-05-04 21:11 . init code
/* compile.c */
//TODO 初步成形
#include <windows.h>
#include "trie.c"
#define BAD_HANDLE(x) (x == INVALID_HANDLE_VALUE || x == NULL)
#define TYPE_INVALID 0
#define TYPE_SIGN 1
#define TYPE_WORD 2
#define TYPE_RESULT 3
struct Item {
DWORD dwType;
LPSTR lpszWord;
};
struct Trie g_Vars;
struct Item g_ItemStack[0x40];
DWORD g_dwStackPtr = 0;
BOOL GetLine(HANDLE hIn, LPSTR lpszBuffer, DWORD dwSize){
DWORD dwRead;
DWORD dwIndex;
ReadFile(hIn, lpszBuffer, dwSize, &dwRead, NULL);
for(dwIndex = 0; dwIndex < dwRead; dwIndex++){
if(lpszBuffer[dwIndex] == '\r'){
lpszBuffer[dwIndex] = '\0';
if(dwIndex + 1 < dwRead && lpszBuffer[dwIndex + 1] == '\n'){
SetFilePointer(hIn, dwIndex - dwRead + 2, NULL, FILE_CURRENT);
return TRUE;
}
SetFilePointer(hIn, dwIndex - dwRead + 1, NULL, FILE_CURRENT);
return TRUE;
}
if(lpszBuffer[dwIndex] == '\n'){
lpszBuffer[dwIndex] = '\0';
SetFilePointer(hIn, dwIndex - dwRead + 1, NULL, FILE_CURRENT);
return TRUE;
}
}
return FALSE;
}
BYTE CharType(CHAR c){
static BYTE bList[0x100] = {0};
if(c == -1){
DWORD dwIndex;
LPCSTR lpszSeq;
lpszSeq = "-_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
dwIndex = 0;
while(lpszSeq[dwIndex])
bList[(BYTE)lpszSeq[dwIndex++]] = 1;
lpszSeq = "+-*/%&^|!><=;,";
dwIndex = 0;
while(lpszSeq[dwIndex])
bList[(BYTE)lpszSeq[dwIndex++]] = 2;
lpszSeq = "\t\b\r\n ";
dwIndex = 0;
while(lpszSeq[dwIndex])
bList[(BYTE)lpszSeq[dwIndex++]] = 3;
return 0;
}
return bList[(BYTE)c];
}
BYTE SignPriority(CHAR c){
static BYTE bList[0x100] = {
['='] = 1,
['&'] = 2,
['|'] = 2,
['!'] = 2,
['^'] = 2,
['>'] = 3,
['<'] = 3,
['+'] = 4,
['-'] = 4,
['*'] = 5,
['/'] = 5,
['%'] = 5,
};
return bList[(BYTE)c];
}
void LoadVariable(HANDLE hOut, struct Item* pVar){
static CHAR cBuffer[0x40];
DWORD dwLength;
if(pVar->dwType == TYPE_WORD){
if((*pVar->lpszWord >= '0' && *pVar->lpszWord <= '9') || *pVar->lpszWord == '-'){
dwLength = wsprintfA(cBuffer, "push %s\n", pVar->lpszWord);
WriteFile(hOut, cBuffer, dwLength, NULL, NULL);
}else{
dwLength = wsprintfA(cBuffer, "load %lu\n", *((LPDWORD)TrieQuery(&g_Vars, pVar->lpszWord)));
WriteFile(hOut, cBuffer, dwLength, NULL, NULL);
}
}
}
void StoreVariable(HANDLE hOut, struct Item* pVar){
static CHAR cBuffer[0x40];
DWORD dwLength;
dwLength = wsprintfA(cBuffer, "store %lu\n", *((LPDWORD)TrieQuery(&g_Vars, pVar->lpszWord)));
WriteFile(hOut, cBuffer, dwLength, NULL, NULL);
}
void op_mov(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + (--g_dwStackPtr));
StoreVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
}
void op_and(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + (--g_dwStackPtr));
LoadVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
WriteFile(hOut, "and\n", 4, NULL, NULL);
g_ItemStack[g_dwStackPtr - 1].dwType = TYPE_RESULT;
}
void op_or(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + (--g_dwStackPtr));
LoadVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
WriteFile(hOut, "or\n", 3, NULL, NULL);
g_ItemStack[g_dwStackPtr - 1].dwType = TYPE_RESULT;
}
void op_not(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
WriteFile(hOut, "not\n", 4, NULL, NULL);
g_ItemStack[g_dwStackPtr - 1].dwType = TYPE_RESULT;
}
void op_xor(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + (--g_dwStackPtr));
LoadVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
WriteFile(hOut, "xor\n", 4, NULL, NULL);
g_ItemStack[g_dwStackPtr - 1].dwType = TYPE_RESULT;
}
void op_cmpg(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + (--g_dwStackPtr));
LoadVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
WriteFile(hOut, "cmpg\n", 5, NULL, NULL);
g_ItemStack[g_dwStackPtr - 1].dwType = TYPE_RESULT;
}
void op_cmpl(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + (--g_dwStackPtr));
LoadVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
WriteFile(hOut, "cmpl\n", 5, NULL, NULL);
g_ItemStack[g_dwStackPtr - 1].dwType = TYPE_RESULT;
}
void op_add(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + (--g_dwStackPtr));
LoadVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
WriteFile(hOut, "add\n", 4, NULL, NULL);
g_ItemStack[g_dwStackPtr - 1].dwType = TYPE_RESULT;
}
void op_sub(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + (--g_dwStackPtr));
LoadVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
WriteFile(hOut, "sub\n", 4, NULL, NULL);
g_ItemStack[g_dwStackPtr - 1].dwType = TYPE_RESULT;
}
void op_mul(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + (--g_dwStackPtr));
LoadVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
WriteFile(hOut, "mul\n", 4, NULL, NULL);
g_ItemStack[g_dwStackPtr - 1].dwType = TYPE_RESULT;
}
void op_div(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + (--g_dwStackPtr));
LoadVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
WriteFile(hOut, "div\n", 4, NULL, NULL);
g_ItemStack[g_dwStackPtr - 1].dwType = TYPE_RESULT;
}
void op_rem(HANDLE hOut){
LoadVariable(hOut, g_ItemStack + (--g_dwStackPtr));
LoadVariable(hOut, g_ItemStack + g_dwStackPtr - 1);
WriteFile(hOut, "rem\n", 4, NULL, NULL);
g_ItemStack[g_dwStackPtr - 1].dwType = TYPE_RESULT;
}
void SignOperation(CHAR c, HANDLE hOut){
static void(*pHandlers[0x100])(HANDLE) = {
['='] = op_mov,
['&'] = op_and,
['|'] = op_or,
['!'] = op_not,
['^'] = op_xor,
['>'] = op_cmpg,
['<'] = op_cmpl,
['+'] = op_add,
['-'] = op_sub,
['*'] = op_mul,
['/'] = op_div,
['%'] = op_rem,
};
if(pHandlers[(BYTE)c])
pHandlers[(BYTE)c](hOut);
}
BYTE GetNextWord(LPCSTR lpszLine, LPSTR lpszWord, DWORD dwSize){
static DWORD dwIndex;
DWORD dwPos = 0;
if(lpszLine == NULL){
dwIndex = 0;
return 0;
}
while(lpszLine[dwIndex]){
switch (CharType(lpszLine[dwIndex])) {
case 0:
return TYPE_INVALID;
case 1:
if(dwPos < dwSize)
lpszWord[dwPos++] = lpszLine[dwIndex];
break;
case 2:
if(dwPos){
if(dwPos < dwSize)
lpszWord[dwPos] = '\0';
return TYPE_WORD;
}
if(dwSize)
*lpszWord = lpszLine[dwIndex];
if(dwSize > 1)
lpszWord[1] = '\0';
dwIndex++;
return TYPE_SIGN;
case 3:
if(dwPos){
if(dwPos < dwSize)
lpszWord[dwPos] = '\0';
return TYPE_WORD;
}
break;
}
dwIndex++;
}
if(dwPos){
if(dwPos < dwSize)
lpszWord[dwPos] = '\0';
return TYPE_WORD;
}
return 0;
}
void ParseExpression(struct Item* pItems, DWORD dwStart, DWORD dwEnd, HANDLE hOut){
DWORD dwIndex;
DWORD dwMin = 0xFFFFFFFF;
DWORD dwPos = -1;
//if(dwStart == dwEnd) error;
if(dwStart + 1 == dwEnd){
if(pItems[dwStart].dwType == TYPE_WORD){
g_ItemStack[g_dwStackPtr++] = pItems[dwStart];
}
return;
}
for(dwIndex = dwStart; dwIndex < dwEnd; dwIndex++)
if(pItems[dwIndex].dwType == TYPE_SIGN && SignPriority(*pItems[dwIndex].lpszWord) <= dwMin){
dwMin = SignPriority(*pItems[dwIndex].lpszWord);
dwPos = dwIndex;
}
if(dwPos == -1)
return;
ParseExpression(pItems, dwStart, dwPos, hOut);
ParseExpression(pItems, dwPos + 1, dwEnd, hOut);
SignOperation(*pItems[dwPos].lpszWord, hOut);
}
void Compile(HANDLE hIn, HANDLE hOut){
static CHAR lpszLine[0x100];
static CHAR lpszWord[0x40];
static struct Item pItems[0x40];
CharType(-1);
while(GetLine(hIn, lpszLine, 0xFF)){
static DWORD dwIndex = 0;
DWORD dwType;
GetNextWord(NULL, NULL, 0);
while((dwType = GetNextWord(lpszLine, lpszWord, 0x3F))){
if(dwType == TYPE_SIGN && !strcmp(lpszWord, ";")){
DWORD dwPtr;
if(!strcmp(pItems->lpszWord, "int")){
static DWORD dwId = 0;
free(pItems->lpszWord);
for(dwPtr = 1; dwPtr < dwIndex; dwPtr++){
if(pItems[dwPtr].dwType == TYPE_WORD)
*((LPDWORD)TrieInsert(&g_Vars, pItems[dwPtr].lpszWord)) = dwId++;
free(pItems[dwPtr].lpszWord);
}
dwIndex = 0;
continue;
}
ParseExpression(pItems, 0, dwIndex, hOut);
g_dwStackPtr = 0;
for(dwPtr = 0; dwPtr < dwIndex; dwPtr++)
free(pItems[dwPtr].lpszWord);
dwIndex = 0;
continue;
}else if(dwIndex < 0x40){
DWORD dwLength = strlen(lpszWord) + 1;
pItems[dwIndex].dwType = dwType;
pItems[dwIndex].lpszWord = malloc(dwLength);
RtlCopyMemory(pItems[dwIndex++].lpszWord, lpszWord, dwLength);
}
}
}
}
int main(int argc, char** argv){
HANDLE hOut;
HANDLE hFile;
HANDLE hOutFile;
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if(argc != 3){
WriteFile(hOut, "Usage: compile.exe [file] [out]\r\n", 33, NULL, NULL);
ExitProcess(1);
}
hFile = CreateFileA(
argv[1],
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(BAD_HANDLE(hFile)){
WriteFile(hOut, "fatal error: Cannot open input file.\r\n", 38, NULL, NULL);
ExitProcess(1);
}
hOutFile = CreateFileA(
argv[2],
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(BAD_HANDLE(hOutFile)){
WriteFile(hOut, "fatal error: Cannot create output file.\r\n", 41, NULL, NULL);
ExitProcess(1);
}
g_Vars = TrieCreate();
Compile(hFile, hOutFile);
CloseHandle(hFile);
CloseHandle(hOutFile);
TrieDelete(&g_Vars);
ExitProcess(0);
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化