interpreter project
This commit is contained in:
1 parent
6692c9c4ee
commit
afb55494e5
6 files changed
+850
No files matched your search
@@ -0,0 +1,69 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Linker files
|
||||
*.ilk
|
||||
|
||||
# Debugger Files
|
||||
*.pdb
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
*.so.*
|
||||
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Build directories
|
||||
build/
|
||||
Build/
|
||||
build-*/
|
||||
|
||||
# CMake generated files
|
||||
CMakeFiles/
|
||||
CMakeCache.txt
|
||||
cmake_install.cmake
|
||||
#Makefile
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.log
|
||||
*.bak
|
||||
*.swp
|
||||
|
||||
# vcpkg
|
||||
vcpkg_installed/
|
||||
|
||||
# debug information files
|
||||
*.dwo
|
||||
|
||||
# test output & cache
|
||||
Testing/
|
||||
.cache/
|
||||
@@ -0,0 +1,27 @@
|
||||
# Fibonacci sequence
|
||||
func fun{
|
||||
if(x <= 2){
|
||||
return(1);
|
||||
}
|
||||
y = 0;
|
||||
x = x - 1;
|
||||
y = fun(x);
|
||||
x = x - 1;
|
||||
return(y + fun(x));
|
||||
};
|
||||
|
||||
# save the Fibonacci sequence of 1 to 15 in an array
|
||||
array arr(15);
|
||||
x = 0;
|
||||
while(x<15){
|
||||
arr[x] = fun(x) + 1000;
|
||||
x = x + 1;
|
||||
}
|
||||
|
||||
puts("Fibonacci sequence:");
|
||||
# print the Fibonacci sequence of 1 to 15
|
||||
i = 0;
|
||||
while(i < 15){
|
||||
print(arr[i]);
|
||||
i=i+1;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
a = 5;
|
||||
b = "ok";
|
||||
|
||||
print(5);
|
||||
puts(b);
|
||||
@@ -0,0 +1,6 @@
|
||||
func f_test{
|
||||
return(0);
|
||||
};
|
||||
|
||||
r = f_test();
|
||||
print(r);
|
||||
@@ -0,0 +1,2 @@
|
||||
print(1);
|
||||
puts("1")
|
||||
+741
@@ -0,0 +1,741 @@
|
||||
/* 魔改自github tryC项目。手写简易的解释器,我们
|
||||
* 将用它来作为操作界面的shell。
|
||||
*
|
||||
* 也许我们可以增加一些字符串赋值、拼接的能力
|
||||
* 同时未来也需要加入系统调用的能力
|
||||
*
|
||||
*
|
||||
* 20250827(qing): 增加了宽字符支持。
|
||||
* 20250827(qing): 修复了Str漏匹配的BUG
|
||||
* 20250827(qing): 该脚本在操作不当的情况下可能会发生内存泄漏
|
||||
* 20250827(qing): 使用longjmp()代替exit()
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include "console.h"
|
||||
#define POOLSIZE (1 * 128) /* 任意大小 */
|
||||
#define SYMTABSIZE (1 * 128) /* !符号表栈的大小 */
|
||||
#define MAXNAMESIZE 16 /* 变量/函数名称的长度 */
|
||||
#define RETURNFLAG DBL_MAX /* 表明函数中已经出现return语句 */
|
||||
|
||||
|
||||
typedef struct symStruct { /* 该结构体表示存储在符号表中的一个符号 */
|
||||
int type; /* 符号的类型:Num, Char, Str, Array, Func */
|
||||
wchar_t name[MAXNAMESIZE]; /* 记录符号名称 */
|
||||
double value; /* 记录符号的值,或者字符串或数组的长度 */
|
||||
union {
|
||||
wchar_t *funcp; /* 指向一个数组或者一个函数 */
|
||||
struct symStruct* list;
|
||||
} pointer;
|
||||
int levelNum; /* 表明声明的嵌套层级 */
|
||||
} symbol;
|
||||
static symbol symtab[SYMTABSIZE];
|
||||
static int symPointer = 0; /* 符号表栈指针 */
|
||||
static int currentlevel = 0; /* 当前嵌套层级 */
|
||||
|
||||
static wchar_t *src, *old_src; /* 当前正处理的文本 */
|
||||
static wchar_t *p_src; /* 用于定位释放点 */
|
||||
static int top_src = 0;
|
||||
|
||||
|
||||
enum { /* 解释器状态枚举 (使用int直接接受匿名枚举) */
|
||||
debug, run
|
||||
};
|
||||
static int compileState = run; /* 当前解释器状态 */
|
||||
|
||||
static double return_val = 0; /* 用于保存函数的返回值 */
|
||||
|
||||
|
||||
enum { /* 标记和类别(运算符放最后并按优先级排序) */
|
||||
Num = 128, Char, Str, Array, Func,
|
||||
Else, If, Return, While, Print, Puts, Read,
|
||||
Assign, OR, AND, Equal, Sym, FuncSym, ArraySym, Void,
|
||||
Nequal, LessEqual, GreatEqual
|
||||
};
|
||||
static int token; /* 当前标记类型 */
|
||||
union tokenValue {
|
||||
symbol *ptr; /* 在返回字符串或符号地址用于赋值时使用 */
|
||||
double val; /* 用于字符或数字时标记值 */
|
||||
} ;
|
||||
|
||||
static union tokenValue token_val;
|
||||
|
||||
/*--------------- 函数声明 ---------------*/
|
||||
static double function();
|
||||
static double statement();
|
||||
static int boolOR(); /* 用于辅助IF和WHILE词元 */
|
||||
static int boolAND();
|
||||
static int boolexp();
|
||||
static double expression();
|
||||
static double factor();
|
||||
static double term();
|
||||
static void match(int tk);
|
||||
static void next();
|
||||
/////
|
||||
static void clear(int level);
|
||||
static void clearThis(); /* 20260707(qing): 增加一个clearThis()函数,用于释放变量 */
|
||||
static void __exit();
|
||||
/* ------------------- 词法分析 -------------------*/
|
||||
|
||||
/* 输入字符串的下一个标记 */
|
||||
static void next() {
|
||||
wchar_t *last_pos;
|
||||
while(token = *src) { /* 逐字扫描 */
|
||||
++src;
|
||||
if (token == L'\n') { /* 记录新行的起点 */
|
||||
//if (compileState == debug)
|
||||
// wprintf(L"%.*ls", (int)(src-old_src), old_src);
|
||||
old_src = src;
|
||||
}
|
||||
else if (token == L'#') { /* 跳过注释 */
|
||||
while(*src != 0 && *src != L'\n') {
|
||||
src++;
|
||||
}
|
||||
}
|
||||
/* ---- 检查到标识符 ---- */
|
||||
else if ((token >= L'a' && token <= L'z') || (token >= L'A' && token <= L'Z') || (token == L'_') || (token > 0x7F)) {
|
||||
last_pos = src -1; /* 程序标识符 */
|
||||
wchar_t nameBuffer[MAXNAMESIZE];
|
||||
nameBuffer[0] = token; /* 扫描标识符 */
|
||||
while ((*src >= L'a' && *src <= L'z') || (*src >= L'A' && *src <= L'Z') || (*src >= L'0' && *src <= L'9') || (*src == L'_') || (*src > 0x7f)) {
|
||||
nameBuffer[src-last_pos] = *src;
|
||||
src++;
|
||||
}
|
||||
nameBuffer[src-last_pos] = 0; /* 获取标识符名 */
|
||||
int i;
|
||||
for (i=symPointer-1; i>=0; --i) { /* 在符号表中搜索符号 */
|
||||
if (wcscmp(nameBuffer, symtab[i].name) == 0) { /* 如果找到符号:根据符号类型返回标记 */
|
||||
|
||||
if (symtab[i].type == Num || symtab[i].type == Char) {
|
||||
token_val.ptr = &symtab[i];
|
||||
token = Sym;
|
||||
}
|
||||
else if (symtab[i].type == Str) { /* 20250827(qing): 新增此分支,修复BUG */
|
||||
token = Str;
|
||||
token_val.ptr = (symbol *)symtab[i].pointer.funcp;
|
||||
}
|
||||
else if (symtab[i].type == FuncSym) {
|
||||
token_val.ptr = &symtab[i];
|
||||
token = symtab[i].type;
|
||||
}
|
||||
else if (symtab[i].type == ArraySym) {
|
||||
token_val.ptr = &symtab[i];
|
||||
token = symtab[i].type;
|
||||
}
|
||||
else {
|
||||
if (symtab[i].type == Void) {
|
||||
token = Sym;
|
||||
token_val.ptr = &symtab[i];
|
||||
}
|
||||
else { // ???
|
||||
token = symtab[i].type;
|
||||
token_val.ptr = NULL; /* 以防万一,为当前记号存储器赋个值!
|
||||
* 因为Array记号可能到这里来,它会在检查失败后检查释放 */
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
wcscpy(symtab[symPointer].name, nameBuffer); /* 如果标记未被发现,创建一个新的 */
|
||||
symtab[symPointer].levelNum = currentlevel;
|
||||
symtab[symPointer].type = Void;
|
||||
token_val.ptr = &symtab[symPointer];
|
||||
symPointer++;
|
||||
token = Sym;
|
||||
return;
|
||||
}
|
||||
else if (token >= L'0' && token <= L'9') {
|
||||
token_val.val = (double)token - L'0';
|
||||
while (*src >= L'0' && *src <= L'9') {
|
||||
token_val.val = token_val.val * 10.0 + *src++ - L'0';
|
||||
}
|
||||
if (*src == L'.') {
|
||||
src++;
|
||||
int countDig = 1;
|
||||
while (*src >= L'0' && *src <= L'9') {
|
||||
token_val.val = token_val.val + ((double)(*src++) - L'0') / (10.0 * countDig++);
|
||||
}
|
||||
}
|
||||
token = Num;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 字符 */
|
||||
else if (token == L'\'') {
|
||||
token_val.val = *src++;
|
||||
token = Char;
|
||||
src++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 字符串 */
|
||||
else if (token == L'"') {
|
||||
last_pos = src;
|
||||
int numCount = 0;
|
||||
while (*src != 0 && *src != token) {
|
||||
src ++;
|
||||
numCount ++;
|
||||
}
|
||||
if (*src) { /* TODO: 解析出字符串就会创建动态内存,那么可能会有风险! */
|
||||
*src = 0;
|
||||
token_val.ptr = malloc(sizeof(wchar_t) * (numCount + 1));
|
||||
*(wchar_t*)token_val.ptr = L'0';
|
||||
wcscpy((wchar_t*)token_val.ptr, last_pos);
|
||||
*src = token;
|
||||
src++;
|
||||
}
|
||||
token = Str;
|
||||
return;
|
||||
}
|
||||
|
||||
/* == 和 = */
|
||||
else if (token == L'=') {
|
||||
if (*src == L'=') {
|
||||
src++;
|
||||
token = Equal;
|
||||
}
|
||||
else {token = Assign;}
|
||||
return;
|
||||
}
|
||||
|
||||
/* != */
|
||||
else if (token == L'!') {
|
||||
if (*src == L'=') {
|
||||
src++;
|
||||
token = Nequal;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* <= 或 < */
|
||||
else if (token == L'<') {
|
||||
if (*src == L'=') {
|
||||
src ++;
|
||||
token = LessEqual;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* >= 或 > */
|
||||
else if (token == L'>') {
|
||||
if (*src == L'=') {
|
||||
src++;
|
||||
token = GreatEqual;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* || */
|
||||
else if (token == L'|') {
|
||||
if (*src == L'|') {
|
||||
src++;
|
||||
token = OR;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* && */
|
||||
else if (token == L'&') {
|
||||
if ( *src == L'&') {
|
||||
src++;
|
||||
token=AND;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* 保持以在别处解析 */
|
||||
else if ( token == L'*' || token == L'/' || token == L';' || token == L',' || token == L'+' || token == L'-' ||
|
||||
token == L'(' || token == L')' || token == L'{' || token == L'}' || token == L'[' || token == L']') {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 空格、制表符 */
|
||||
else if (token == L' ' || token == L'\t') { }
|
||||
|
||||
/* 不认识 */
|
||||
else {
|
||||
//wprintf(L"unexpected token: %d\n", token);
|
||||
printtovga(L"unexpected token\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void clear(int level) {
|
||||
for (int i=symPointer-1; i>=0; i--) {
|
||||
token_val.ptr = &symtab[i];
|
||||
if ( token_val.ptr->levelNum >= level ) {
|
||||
clearThis();
|
||||
}
|
||||
else { break; }
|
||||
}
|
||||
}
|
||||
|
||||
/* 20250827(QING): 在这里检测pointer联合字段是否为空,不为空就表明有值先释放 */
|
||||
static void clearThis() {
|
||||
//printf("Clear a Symbol: %s\n", token_val.ptr->name);
|
||||
if (token_val.ptr->type == Str && token_val.ptr->pointer.funcp)
|
||||
free(token_val.ptr->pointer.funcp);
|
||||
else if (token_val.ptr->type == ArraySym && token_val.ptr->pointer.list)
|
||||
free(token_val.ptr->pointer.list);
|
||||
}
|
||||
|
||||
/* 检查是否匹配 */
|
||||
static void match(int tk) {
|
||||
if (token == tk) {
|
||||
if (compileState==debug) {
|
||||
if (iswprint(tk)) { /* 该字符是否能够打印 */
|
||||
//wprintf(L"match: %lc\n", tk);
|
||||
}
|
||||
else {
|
||||
//wprintf(L"match: %d\n", tk);
|
||||
;
|
||||
}
|
||||
}
|
||||
next(); /* 检查下一个标记 */
|
||||
}
|
||||
else { /* 直接让程序死亡,在单片机上似乎不妥 */
|
||||
//wprintf(L"line %.*ls:expected token: %d\n", (int)(src - old_src), old_src, tk);
|
||||
printtovga(L"unexpected token\n");
|
||||
__exit(-1);
|
||||
//clearThis();
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------- 语法分析与执行 --------------------------*/
|
||||
static double term() {
|
||||
double temp = factor();
|
||||
while (token == L'*' || token == L'/') {
|
||||
if (token == L'*') {
|
||||
match(L'*');
|
||||
temp *= factor();
|
||||
}
|
||||
else {
|
||||
match(L'/');
|
||||
temp /= factor();
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
static double factor() {
|
||||
double temp = 0;
|
||||
if (token == L'(') {
|
||||
match(L'(');
|
||||
temp = expression();
|
||||
match(L')');
|
||||
}
|
||||
else if (token == Num || token == Char) {
|
||||
temp = token_val.val;
|
||||
match(token);
|
||||
}
|
||||
else if (token == Sym) {
|
||||
temp = token_val.ptr->value;
|
||||
match(Sym);
|
||||
}
|
||||
else if (token == ArraySym) {
|
||||
symbol *ptr = token_val.ptr;
|
||||
match(ArraySym);
|
||||
match(L'[');
|
||||
int index = (int)expression();
|
||||
if (index >= 0 && index < ptr->value) {
|
||||
temp = ptr->pointer.list[index].value;
|
||||
}
|
||||
match(L']');
|
||||
}
|
||||
else if (token == FuncSym) { /* 处理函数调用 */
|
||||
temp = function();
|
||||
}
|
||||
else {
|
||||
//printf("Unknow token: %d.\n", token);
|
||||
printtovga(L"Unknow token\n");
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* 加减法表达式 */
|
||||
static double expression() {
|
||||
double temp = term();
|
||||
while (token == L'+' || token == L'-') {
|
||||
if (token == L'+') {
|
||||
match(L'+');
|
||||
temp += term();
|
||||
}
|
||||
else {
|
||||
match(L'-');
|
||||
temp -= term();
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
static int boolexp() {
|
||||
if (token == L'(') {
|
||||
match(L'(');
|
||||
int result = boolOR();
|
||||
match(L')');
|
||||
return result;
|
||||
}
|
||||
else if (token == L'!') {
|
||||
match(L'!');
|
||||
return boolexp();
|
||||
}
|
||||
double temp = expression();
|
||||
if (token == L'>') {
|
||||
match(L'>');
|
||||
return temp > expression();
|
||||
}
|
||||
else if (token == L'<') {
|
||||
match(L'<');
|
||||
return temp < expression();
|
||||
}
|
||||
else if (token == GreatEqual) {
|
||||
match(GreatEqual);
|
||||
return temp >= expression();
|
||||
}
|
||||
else if (token == LessEqual) {
|
||||
match(LessEqual);
|
||||
return temp <= expression();
|
||||
}
|
||||
else if (token == Equal) {
|
||||
match(Equal);
|
||||
return temp == expression();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void skipBoolExpr() {
|
||||
int count = 0;
|
||||
while (token && !(token == L')' && count == 0)) {
|
||||
if (token == L'(') count++;
|
||||
if (token == L')') count--;
|
||||
token = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int boolAND() {
|
||||
int val = boolexp();
|
||||
while (token == AND) {
|
||||
match(AND);
|
||||
if (val == 0){
|
||||
skipBoolExpr();
|
||||
return 0; // short cut
|
||||
}
|
||||
val = val & boolexp();
|
||||
if (val == 0) return 0;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static int boolOR() {
|
||||
int val = boolAND();
|
||||
while (token == OR) {
|
||||
match(OR);
|
||||
if (val == 1){
|
||||
skipBoolExpr();
|
||||
return 1; // short cut
|
||||
}
|
||||
val = val | boolAND();
|
||||
if (val == 1) return 1;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static void skipStatments() {
|
||||
if(token == L'{')
|
||||
token = *src++;
|
||||
int count = 0;
|
||||
while (token && !(token == L'}' && count == 0)) {
|
||||
if (token == L'}') count++;
|
||||
if (token == L'{') count--;
|
||||
token = *src++;
|
||||
}
|
||||
match(L'}');
|
||||
}
|
||||
|
||||
/* 解析一个句子 */
|
||||
static double statement() {
|
||||
if (token == L'{') {
|
||||
match(L'{');
|
||||
while (token != L'}') {
|
||||
if (RETURNFLAG == statement())
|
||||
return RETURNFLAG;
|
||||
}
|
||||
match(L'}');
|
||||
}
|
||||
else if (token == If) {
|
||||
match(If);
|
||||
match(L'(');
|
||||
int boolresult = boolOR();
|
||||
match(L')');
|
||||
if (boolresult) {
|
||||
if (RETURNFLAG == statement())
|
||||
return RETURNFLAG;
|
||||
}
|
||||
else skipStatments();
|
||||
if (token == Else) {
|
||||
match(Else);
|
||||
if (!boolresult) {
|
||||
if (RETURNFLAG == statement())
|
||||
return RETURNFLAG;
|
||||
}
|
||||
else skipStatments();
|
||||
}
|
||||
}
|
||||
else if (token == While) {
|
||||
match(While);
|
||||
wchar_t* whileStartPos = src;
|
||||
wchar_t* whileStartOldPos = old_src;
|
||||
int boolresult;
|
||||
do {
|
||||
src = whileStartPos;
|
||||
old_src = whileStartOldPos;
|
||||
token = L'('; /* 不加行会报错 */
|
||||
match(L'(');
|
||||
boolresult = boolOR();
|
||||
match(L')');
|
||||
if (boolresult) {
|
||||
if (RETURNFLAG == statement())
|
||||
return RETURNFLAG;
|
||||
}
|
||||
else skipStatments();
|
||||
}while (boolresult);
|
||||
}
|
||||
|
||||
|
||||
/* ---- 给变量赋值 ---- */
|
||||
else if (token == Sym || token == ArraySym) {
|
||||
symbol* s = token_val.ptr;
|
||||
//clearThis(); /* 不知为何需要注释了才能跑 */
|
||||
int tktype = token;
|
||||
int index;
|
||||
match(tktype);
|
||||
if (tktype == ArraySym) {
|
||||
match(L'[');
|
||||
index = expression();
|
||||
match(L']');
|
||||
match(Assign);
|
||||
if (index >= 0 && index < s->value) {
|
||||
s->pointer.list[index].value = expression();
|
||||
}
|
||||
/* TODO: 越界异常 */
|
||||
}
|
||||
else {
|
||||
match(Assign);
|
||||
if (token == Str) {
|
||||
s->pointer.funcp = (wchar_t*)token_val.ptr;
|
||||
s->type = Str;
|
||||
match(Str);
|
||||
}
|
||||
else if (token == Char) {
|
||||
s->value = token_val.val;
|
||||
s->type = Char;
|
||||
match(Char);
|
||||
}
|
||||
else {
|
||||
s->value = expression();
|
||||
s->type = Num;
|
||||
}
|
||||
}
|
||||
match(L';');
|
||||
}
|
||||
else if (token == Array) {
|
||||
match(Array);
|
||||
symbol* s = token_val.ptr;
|
||||
//clearThis();
|
||||
match(Sym);
|
||||
match(L'(');
|
||||
int length = (int)expression();
|
||||
match(L')');
|
||||
s->pointer.list = malloc(sizeof(struct symStruct) * length + 1);
|
||||
for (int i = 0; i < length; ++i)
|
||||
s->pointer.list[i].type = Num;
|
||||
s->value = length;
|
||||
s->type = ArraySym;
|
||||
match(L';');
|
||||
}
|
||||
else if (token == Func) {
|
||||
match(Func);
|
||||
symbol* s = token_val.ptr;
|
||||
//clearThis();
|
||||
s->type = FuncSym;
|
||||
match(Sym);
|
||||
s->pointer.funcp = src;
|
||||
s->value = token;
|
||||
skipStatments();
|
||||
match(L';');
|
||||
}
|
||||
else if (token == Return) {
|
||||
match(Return);
|
||||
match(L'(');
|
||||
return_val = expression();
|
||||
match(L')');
|
||||
match(L';');
|
||||
return RETURNFLAG;
|
||||
}
|
||||
else if (token == Print || token == Read || token == Puts) {
|
||||
int func = token;
|
||||
double temp;
|
||||
match(func);
|
||||
match(L'(');
|
||||
switch (func) {
|
||||
case Print:
|
||||
temp = expression();
|
||||
wchar_t buf[16];
|
||||
swprintf(buf, 16, L"%lf\n", temp);
|
||||
printtovga(buf);
|
||||
break;
|
||||
case Puts:
|
||||
/* 这一句切换不过来 */
|
||||
//wprintf(L"%ls\n", (wchar_t*)token_val.ptr);
|
||||
printtovga((wchar_t*)token_val.ptr);
|
||||
match(Str);
|
||||
break;
|
||||
case Read: /* 单片机上等下支持 */
|
||||
//wscanf(L"%lf", &token_val.ptr->value);
|
||||
token_val.ptr->value = -1;
|
||||
token_val.ptr->type = Num;
|
||||
match(Sym);
|
||||
}
|
||||
match(L')');
|
||||
match(L';');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static double function() {
|
||||
currentlevel++;
|
||||
return_val = 0;
|
||||
|
||||
symbol* s = token_val.ptr;
|
||||
match(FuncSym);
|
||||
match(L'(');
|
||||
while (token != L')') {
|
||||
symtab[symPointer] = *token_val.ptr;
|
||||
wcscpy(symtab[symPointer].name, token_val.ptr->name);
|
||||
symtab[symPointer].levelNum = currentlevel;
|
||||
symPointer++;
|
||||
match(Sym);
|
||||
if (token == L',')
|
||||
match(L',');
|
||||
}
|
||||
match(L')');
|
||||
wchar_t* startPos = src;
|
||||
wchar_t* startOldPos = old_src;
|
||||
int startToken = token;
|
||||
old_src = src = s->pointer.funcp;
|
||||
token = (int)s->value;
|
||||
statement();
|
||||
src = startPos;
|
||||
old_src = startOldPos;
|
||||
token = startToken;
|
||||
|
||||
while (symtab[symPointer - 1].levelNum == currentlevel) {
|
||||
symPointer--;
|
||||
}
|
||||
currentlevel--;
|
||||
return return_val;
|
||||
}
|
||||
/*----------------------------------------------------------------*/
|
||||
int init_tryc() {
|
||||
|
||||
/* 将所有字段赋值为0 */
|
||||
memset(symtab, 0, sizeof(symtab));
|
||||
|
||||
int i; /* 用于阅读定位 */
|
||||
src = L"array func else if return while print puts read";
|
||||
for (i = Array; i <= Read; ++i) {
|
||||
next();
|
||||
symtab[symPointer -1].type = i;
|
||||
}
|
||||
|
||||
if (!(src = old_src = p_src = (wchar_t*)malloc(POOLSIZE))) {
|
||||
//wprintf(L"could not malloc(%d) for source area\n", POOLSIZE);
|
||||
printtovga(L"could not malloc for source aream\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
top_src = 0;
|
||||
src[0] = L'\0'; // add EOF character
|
||||
}
|
||||
|
||||
void free_tryc() {
|
||||
|
||||
free(p_src);
|
||||
}
|
||||
|
||||
int enqueue_tryc(wchar_t wc) {
|
||||
|
||||
if (top_src >= POOLSIZE - 1) {
|
||||
return -1;
|
||||
}
|
||||
src[top_src] = wc;
|
||||
src[++top_src] = L'\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eval_tryc() {
|
||||
|
||||
if (*src == L'\0') return;
|
||||
|
||||
next();
|
||||
while (token != L'\0') {
|
||||
statement();
|
||||
}
|
||||
src = p_src;
|
||||
|
||||
top_src = 0;
|
||||
src[0]= L'\0';
|
||||
|
||||
}
|
||||
|
||||
void __exit() {
|
||||
while (1);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include "fcntl.h"
|
||||
#include "unistd.h"
|
||||
#include "locale.h"
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
init_tryc();
|
||||
|
||||
|
||||
int i;
|
||||
setlocale(LC_ALL, "");
|
||||
wchar_t wc;
|
||||
i = 0;
|
||||
FILE *file = fopen(argv[1], "r");
|
||||
if (!file) {
|
||||
perror("fopen");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ((wc = fgetwc(file)) != WEOF) {
|
||||
src[i++] = wc;
|
||||
}
|
||||
|
||||
|
||||
src[i] = L'\0'; // add EOF character
|
||||
fclose(file);
|
||||
|
||||
eval_tryc();
|
||||
|
||||
clear(0);
|
||||
free_tryc();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Reference in new issue
Block a user