Skip to content

Commit 3843de5

Browse files
committed
Merge branch 'orgainize-util'
2 parents b60d4fd + a36886f commit 3843de5

File tree

3 files changed

+163
-141
lines changed

3 files changed

+163
-141
lines changed

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ include_directories("${laco_SOURCE_DIR}/src" "${DEPS_DIR}/linenoise")
44

55
set(SOURCE ${DEPS_DIR}/linenoise/linenoise.c
66
main.c util.c util/print.c
7+
util/line.c
78
commands/debugger.c
89
flags.c commands.c laco.c)
910

src/util.c

Lines changed: 2 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,12 @@
11
#include "util.h"
22

3-
#include <stdlib.h>
43
#include <stdbool.h>
4+
#include <stdio.h>
5+
#include <stdlib.h>
56
#include <string.h>
67

7-
#include <lua.h>
8-
#include <lauxlib.h>
9-
10-
#include "linenoise.h"
11-
#include "commands.h"
128
#include "laco.h"
139

14-
/* Check if line is incomplete */
15-
static bool incomplete(lua_State* L, int status) {
16-
bool result = false;
17-
18-
if(status == LUA_ERRSYNTAX) {
19-
size_t lmess;
20-
const char* mess = lua_tolstring(L, -1, &lmess);
21-
22-
/* Check if the error ends in '<eof>' */
23-
size_t eof_size = sizeof(LUA_QL("<eof>")) - 1;
24-
const char* mess_end = mess + lmess - eof_size;
25-
if(strstr(mess, LUA_QL("<eof>")) == mess_end) {
26-
lua_pop(L, 1);
27-
result = true;
28-
}
29-
}
30-
31-
return result;
32-
}
33-
34-
/* Check if line can be printed */
35-
static bool is_printable(lua_State* L, int status) {
36-
bool result = false;
37-
38-
if(status == LUA_ERRSYNTAX) {
39-
const char* mess = lua_tostring(L, -1);
40-
41-
bool is_literal = strstr(mess, "unexpected symbol") != NULL;
42-
bool is_variable = strstr(mess, "'=' expected") != NULL;
43-
44-
if(is_literal || is_variable) {
45-
/* pop off error message */
46-
lua_pop(L, 1);
47-
48-
const char* literal = lua_tostring(L, -1);
49-
lua_pop(L, 1);
50-
51-
lua_pushfstring(L, "return %s", literal);
52-
53-
result = true;
54-
}
55-
} else if(lua_type(L, -1) == LUA_TFUNCTION) {
56-
const char* func = lua_tostring(L, -2);
57-
58-
/* check for a return statement */
59-
bool is_assignment = strstr(func, "=");
60-
61-
if(!strstr(func, "return ") && !is_assignment) {
62-
lua_pop(L, 2);
63-
lua_pushfstring(L, "return %s", func);
64-
65-
result = true;
66-
}
67-
}
68-
69-
return result;
70-
}
71-
72-
static char* get_line(LacoState* laco, const char* prompt) {
73-
char* line = linenoise(prompt);
74-
75-
if(line != NULL) {
76-
linenoiseHistoryAdd(line);
77-
78-
if(line[0] == ':') {
79-
laco_handle_command(laco, line);
80-
}
81-
}
82-
83-
return line;
84-
}
85-
86-
/* Push a line to the stack and store in history */
87-
static bool pushline(LacoState* laco, bool isFirstLine) {
88-
const char* prompt = (isFirstLine) ? "> " : "... ";
89-
char* line = get_line(laco, prompt);
90-
lua_State* L = laco_get_laco_lua_state(laco);
91-
bool result = false;
92-
93-
if(line != NULL) {
94-
lua_pushstring(L, line);
95-
96-
free(line);
97-
result = true;
98-
}
99-
100-
return result;
101-
}
102-
10310
static inline void ignore_extra(const char chr, char** string_ptr) {
10411
if(*string_ptr == NULL) return;
10512

@@ -110,52 +17,6 @@ static inline void ignore_extra(const char chr, char** string_ptr) {
11017

11118
/* External API */
11219

113-
int laco_load_line(LacoState* laco) {
114-
int status = laco_get_laco_status(laco);
115-
lua_State* L = laco_get_laco_lua_state(laco);
116-
117-
lua_settop(L, 0);
118-
119-
if(!pushline(laco, true)) return -1;
120-
121-
/* Until complete line */
122-
while(true) {
123-
status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1),
124-
"=stdin");
125-
126-
if(is_printable(L, status)) continue;
127-
if(!incomplete(L, status)) break;
128-
if(!pushline(laco, false)) return -1;
129-
130-
lua_pushliteral(L, "\n");
131-
lua_insert(L, -2);
132-
lua_concat(L, 3);
133-
}
134-
lua_remove(L, 1);
135-
laco_set_laco_status(laco, status);
136-
137-
return status;
138-
}
139-
140-
void laco_handle_line(LacoState* laco) {
141-
int status = laco_get_laco_status(laco);
142-
lua_State* L = laco_get_laco_lua_state(laco);
143-
144-
if(status == 0) {
145-
status = lua_pcall(L, 0, LUA_MULTRET, 0);
146-
}
147-
148-
laco_report_error(laco, status);
149-
150-
if(status == 0 && lua_gettop(L) > 0) {
151-
status = laco_print_type(laco);
152-
153-
laco_report_error(laco, status);
154-
}
155-
156-
laco_set_laco_status(laco, status);
157-
}
158-
15920
void laco_kill(LacoState* laco, int status, const char* message) {
16021
laco_destroy_laco_state(laco);
16122

src/util/line.c

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#include "util.h"
2+
3+
#include <stdbool.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
7+
#include <lua.h>
8+
#include <lauxlib.h>
9+
10+
#include "linenoise.h"
11+
12+
#include "commands.h"
13+
#include "laco.h"
14+
15+
/* Check if line is incomplete */
16+
static bool incomplete(lua_State* L, int status) {
17+
size_t lmess;
18+
size_t eof_size;
19+
const char* mess;
20+
const char* mess_end;
21+
22+
bool result = false;
23+
24+
if(status == LUA_ERRSYNTAX) {
25+
mess = lua_tolstring(L, -1, &lmess);
26+
27+
/* Check if the error ends in '<eof>' */
28+
eof_size = sizeof(LUA_QL("<eof>")) - 1;
29+
mess_end = mess + lmess - eof_size;
30+
31+
if(strstr(mess, LUA_QL("<eof>")) == mess_end) {
32+
lua_pop(L, 1);
33+
result = true;
34+
}
35+
}
36+
37+
return result;
38+
}
39+
40+
/* Check if line can be printed */
41+
static bool is_printable(lua_State* L, int status) {
42+
const char* mess;
43+
const char* literal;
44+
const char* func;
45+
bool is_assignment;
46+
bool is_literal;
47+
bool is_variable;
48+
49+
bool result = false;
50+
51+
if(status == LUA_ERRSYNTAX) {
52+
mess = lua_tostring(L, -1);
53+
54+
is_literal = strstr(mess, "unexpected symbol") != NULL;
55+
is_variable = strstr(mess, "'=' expected") != NULL;
56+
57+
if(is_literal || is_variable) {
58+
/* pop off error message */
59+
lua_pop(L, 1);
60+
61+
literal = lua_tostring(L, -1);
62+
lua_pop(L, 1);
63+
64+
lua_pushfstring(L, "return %s", literal);
65+
66+
result = true;
67+
}
68+
} else if(lua_type(L, -1) == LUA_TFUNCTION) {
69+
func = lua_tostring(L, -2);
70+
71+
/* check for a return statement */
72+
is_assignment = strstr(func, "=");
73+
74+
if(!strstr(func, "return ") && !is_assignment) {
75+
lua_pop(L, 2);
76+
lua_pushfstring(L, "return %s", func);
77+
78+
result = true;
79+
}
80+
}
81+
82+
return result;
83+
}
84+
85+
static char* get_line(LacoState* laco, const char* prompt) {
86+
char* line = linenoise(prompt);
87+
88+
if(line != NULL) {
89+
linenoiseHistoryAdd(line);
90+
91+
if(line[0] == ':') {
92+
laco_handle_command(laco, line);
93+
}
94+
}
95+
96+
return line;
97+
}
98+
99+
/* Push a line to the stack and store in history */
100+
static bool pushline(LacoState* laco, bool isFirstLine) {
101+
const char* prompt = (isFirstLine) ? "> " : "... ";
102+
char* line = get_line(laco, prompt);
103+
lua_State* L = laco_get_laco_lua_state(laco);
104+
bool result = false;
105+
106+
if(line != NULL) {
107+
lua_pushstring(L, line);
108+
109+
free(line);
110+
result = true;
111+
}
112+
113+
return result;
114+
}
115+
116+
int laco_load_line(LacoState* laco) {
117+
int status = laco_get_laco_status(laco);
118+
lua_State* L = laco_get_laco_lua_state(laco);
119+
120+
lua_settop(L, 0);
121+
122+
if(!pushline(laco, true)) return -1;
123+
124+
/* Until complete line */
125+
while(true) {
126+
status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1),
127+
"=stdin");
128+
129+
if(is_printable(L, status)) continue;
130+
if(!incomplete(L, status)) break;
131+
if(!pushline(laco, false)) return -1;
132+
133+
lua_pushliteral(L, "\n");
134+
lua_insert(L, -2);
135+
lua_concat(L, 3);
136+
}
137+
lua_remove(L, 1);
138+
laco_set_laco_status(laco, status);
139+
140+
return status;
141+
}
142+
143+
void laco_handle_line(LacoState* laco) {
144+
int status = laco_get_laco_status(laco);
145+
lua_State* L = laco_get_laco_lua_state(laco);
146+
147+
if(status == 0) {
148+
status = lua_pcall(L, 0, LUA_MULTRET, 0);
149+
}
150+
151+
laco_report_error(laco, status);
152+
153+
if(status == 0 && lua_gettop(L) > 0) {
154+
status = laco_print_type(laco);
155+
156+
laco_report_error(laco, status);
157+
}
158+
159+
laco_set_laco_status(laco, status);
160+
}

0 commit comments

Comments
 (0)