Skip to content

Commit 2d5f6e5

Browse files
committed
Merge pull request #41 from elite-lang/dev
fix windows bug
2 parents 068820b + 114b7ac commit 2d5f6e5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2768
-208
lines changed

Builder/src/Worker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ void Worker::Init(LexInterface* l, Parser* p, ScriptRunner* s, CodeGen* c) {
2727
void Worker::Run(const char* input, const char* output) {
2828
Node* node = MakeAST(input);
2929
codegen->PreScan(node);
30-
codegen->Make(node, output, "Main");
30+
codegen->Make(node, output, "");
3131
}
3232

3333
Node* Worker::MakeAST(const char* input) {

LR_Scanner

Preprocessor/CMakeLists.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
cmake_minimum_required(VERSION 2.8)
2+
project(Preprocessor)
3+
4+
if(NOT BUILD_ALL) # BUILD_ALL负责确认是不是所有子项目统一配置构建
5+
SET (CMAKE_BUILD_TYPE Debug)
6+
SET (CMAKE_CXX_COMPILER_ENV_VAR "clang++")
7+
SET (CMAKE_CXX_FLAGS "-std=c++11")
8+
SET (CMAKE_CXX_FLAGS_DEBUG "-g")
9+
SET (CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
10+
SET (CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG")
11+
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
12+
SET (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
13+
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../extlib/lib)
14+
endif()
15+
16+
17+
# 核心路径配置
18+
include_directories(include src ../extlib/include)
19+
file(GLOB_RECURSE source_files ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
20+
if(USE_DYNAMIC)
21+
add_library(preprocessor SHARED ${source_files}) # 使用动态库
22+
else()
23+
add_library(preprocessor STATIC ${source_files}) # 使用静态库
24+
endif()
25+
26+
if(BUILD_TEST)
27+
add_subdirectory(test)
28+
endif()
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef PREPROCESSOR_H
2+
#define PREPROCESSOR_H
3+
4+
#include "lua.hpp"
5+
#include <string>
6+
7+
class Preprocessor {
8+
public:
9+
Preprocessor (const std::string& input, lua_State* L);
10+
virtual ~Preprocessor ();
11+
12+
const std::string& genCode();
13+
const std::string& runCode();
14+
15+
std::string output;
16+
const std::string& input;
17+
std::string code_string;
18+
protected:
19+
lua_State* L;
20+
21+
int add_const_str(std::string::const_iterator p, std::string::const_iterator q);
22+
int pt_size = 0;
23+
24+
};
25+
26+
27+
28+
29+
#endif /* end of include guard: PREPROCESSOR_H */

Preprocessor/src/Preprocessor.cpp

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#include "Preprocessor.h"
2+
#include <cctype>
3+
4+
using namespace std;
5+
6+
7+
const std::string& Preprocessor::genCode() {
8+
std::string script;
9+
10+
std::string::const_iterator b = input.begin();
11+
std::string::const_iterator e = input.end();
12+
bool is_script = false;
13+
if (*b == '#') { ++b; is_script = true; }
14+
for (auto p = input.begin(); p != input.end(); ++p) {
15+
if (*p == '\n') {
16+
if (is_script) { e = p+1; script.append(b, e); }
17+
if (!is_script && *(p+1) == '#') {
18+
e = p+1;
19+
int k = add_const_str(b, e);
20+
script += "__loadStr(";
21+
script += to_string(k);
22+
script += ");\n";
23+
}
24+
if (is_script) b=p+1;
25+
if (*(p+1) == '#') { b=p+1; ++b; is_script = true; }
26+
else { is_script = false; }
27+
}
28+
}
29+
code_string = script;
30+
return code_string;
31+
}
32+
33+
const std::string& Preprocessor::runCode() {
34+
lua_pushglobaltable(L);
35+
lua_pushlightuserdata(L, this);
36+
lua_setfield(L, -2, "__preprocessor");
37+
38+
int error = luaL_loadbuffer(L, code_string.c_str(), code_string.size() ,"chunk") //加载当前script
39+
| lua_pcall(L, 0, 0, 0); // 巧妙的利用或运算符,前面若成功返回0,则执行后面的
40+
41+
if (error) {
42+
printf("====== ERROR! ======\n");
43+
printf("%s\n", lua_tostring(L, -1));
44+
lua_pop(L, 1);/* pop error message from the stack */
45+
return output;
46+
}
47+
48+
return output;
49+
}
50+
51+
52+
int Preprocessor::add_const_str(
53+
std::string::const_iterator p, std::string::const_iterator q) {
54+
string str(p, q);
55+
lua_pushstring(L, str.c_str());
56+
return luaL_ref(L, LUA_REGISTRYINDEX);
57+
}
58+
59+
static std::string add_lua_call(const char*& p) {
60+
auto b = p;
61+
while (isalpha(*p)||isdigit(*p)||(*p=='_')) ++p;
62+
if (*p == '(') {
63+
for (int k = 1; k != 0; ++p) {
64+
if (*p == '(') ++k;
65+
if (*p == ')') --k;
66+
}
67+
}
68+
return string(b, p-b);
69+
}
70+
71+
static int lua_echo (lua_State *L) {
72+
int n = lua_gettop(L); /* number of arguments */
73+
74+
// get the pointer for Class Preprocess
75+
lua_pushglobaltable(L);
76+
lua_getfield(L, -1, "__preprocessor");
77+
Preprocessor* p = (Preprocessor*)lua_topointer(L, -1);
78+
lua_pop(L, 1);
79+
80+
lua_getglobal(L, "tostring");
81+
for (int i=1; i<=n; i++) {
82+
const char *s;
83+
size_t l;
84+
lua_pushvalue(L, -1); /* function to be called */
85+
lua_pushvalue(L, i); /* value to print */
86+
lua_call(L, 1, 1);
87+
s = lua_tolstring(L, -1, &l); /* get result */
88+
if (s == NULL)
89+
return luaL_error(L, "'tostring' must return a string to 'print'");
90+
if (i>1) p->output += '\t';
91+
string data(s, l);
92+
p->output += data;
93+
94+
lua_pop(L, 1); /* pop result */
95+
}
96+
p->output += '\n';
97+
98+
99+
return 0;
100+
}
101+
102+
103+
static int lua_loadStr(lua_State* L) {
104+
lua_gettop(L); /* number of arguments */
105+
106+
int id = lua_tonumber(L, -1);
107+
lua_rawgeti(L, LUA_REGISTRYINDEX, id);
108+
const char* str = lua_tostring(L, -1);
109+
// get the pointer for Class Preprocess
110+
lua_pushglobaltable(L);
111+
lua_getfield(L, -1, "__preprocessor");
112+
Preprocessor* pp = (Preprocessor*)lua_topointer(L, -1);
113+
lua_pushglobaltable(L);
114+
lua_getfield(L, -1, "Escape");
115+
bool b = lua_toboolean(L, -1);
116+
lua_pop(L, 2);
117+
118+
if (b == false)
119+
pp->output += str;
120+
else {
121+
for (const char* p = str; p != 0; ++p) {
122+
if (*p != '$') pp->output += *p;
123+
else {
124+
lua_pushcfunction(L, lua_echo);
125+
string script = add_lua_call(p);
126+
int error = luaL_loadbuffer(L, script.c_str(), script.size() ,"chunk") //加载当前script
127+
| lua_pcall(L, 0, 0, 0); // 巧妙的利用或运算符,前面若成功返回0,则执行后面的
128+
129+
if (error | lua_pcall(L, 0, 0, 0)) {
130+
printf("====== LUA ERROR! ======\n");
131+
printf("%s\n", lua_tostring(L, -1));
132+
lua_pop(L, 1);/* pop error message from the stack */
133+
return 0;
134+
}
135+
}
136+
}
137+
}
138+
139+
lua_pop(L, 3);
140+
return 0;
141+
}
142+
143+
Preprocessor::Preprocessor (const std::string& input, lua_State* L)
144+
: input(input) {
145+
this->L = L;
146+
lua_register(L, "__loadStr", lua_loadStr);
147+
lua_register(L, "echo", lua_echo);
148+
149+
lua_pushglobaltable(L);
150+
lua_pushboolean(L, 0);
151+
lua_setfield(L, -2, "Escape");
152+
}
153+
154+
Preprocessor::~Preprocessor () {
155+
156+
}

Preprocessor/test/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
enable_testing()
2+
find_package(GTest REQUIRED)
3+
4+
include_directories (${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../include)
5+
include_directories (${GTEST_INCLUDE_DIRS})
6+
file(GLOB_RECURSE test_source_files ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
7+
8+
add_executable (pp_test ${test_source_files})
9+
10+
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../extlib)
11+
12+
target_link_libraries(pp_test preprocessor lua ${GTEST_BOTH_LIBRARIES} pthread)
13+
14+
add_test(EstringTest pp_test)
15+
16+
add_custom_target( runtest ALL DEPENDS pp_test)
17+
18+
add_custom_command(TARGET runtest
19+
POST_BUILD
20+
COMMAND pp_test)

Preprocessor/test/PPTest.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* @Author: sxf
3+
* @Date: 2015-12-16 12:02:18
4+
* @Last Modified by: sxf
5+
* @Last Modified time: 2016-03-05 17:01:18
6+
*/
7+
8+
#include <gtest/gtest.h>
9+
#include "Preprocessor.h"
10+
11+
#include <iostream>
12+
#include <fstream>
13+
using namespace std;
14+
15+
static std::string fileReader(const char* path) {
16+
std::ifstream t(path, std::ios::binary);
17+
std::string str;
18+
19+
t.seekg(0, std::ios::end);
20+
str.reserve(t.tellg());
21+
t.seekg(0, std::ios::beg);
22+
23+
str.assign((std::istreambuf_iterator<char>(t)),
24+
std::istreambuf_iterator<char>());
25+
return str;
26+
}
27+
28+
29+
#define __PP_TEST__(name) TEST(PP_##name, name)
30+
31+
__PP_TEST__(Construction)
32+
{
33+
lua_State* L = luaL_newstate();
34+
luaL_openlibs(L);
35+
string data = fileReader("../../test/t1.ecode");
36+
cout << data << endl << endl;
37+
Preprocessor pp(data, L);
38+
cout << "----------------------" << endl;
39+
cout << pp.genCode() << endl << endl;
40+
lua_close(L);
41+
}
42+
43+
44+
__PP_TEST__(Run)
45+
{
46+
lua_State* L = luaL_newstate();
47+
luaL_openlibs(L);
48+
string data = fileReader("../../test/t1.ecode");
49+
Preprocessor pp(data, L);
50+
cout << pp.genCode() << endl << endl;
51+
cout << "---------------------" << endl;
52+
cout << pp.runCode() << endl << endl;
53+
54+
lua_close(L);
55+
}

Preprocessor/test/t1.ecode

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# print('hello ecode')
2+
# Escape = True
3+
# if true then
4+
5+
void print() {
6+
return;
7+
}
8+
9+
# else
10+
11+
int main() {
12+
return 0;
13+
}
14+
15+
# end

conf/parser.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
| <for_state:v> {{ return v; }}
6060
| <return_state:v> {{ return v; }}
6161
| <delete_expr:v> {{ return v; }}
62+
| "break" ";" {{ return makeList(newIDNode("break")) }}
63+
| "continue" ";" {{ return makeList(newIDNode("continue")) }}
6264
;
6365

6466
<if_state> = "if" "(" <expr:exp> ")" <statement:s> {{ return makeList(newIDNode("if"), exp, s) }}

0 commit comments

Comments
 (0)