mirror of
https://github.com/zekexiao/pocketlang.git
synced 2025-02-06 04:37:47 +08:00
Merge pull request #83 from xSavitar/fix-issue-79
Improve REPL to use a byte buffer with `fgetc()` to read line
This commit is contained in:
commit
2b92758b83
29
cli/repl.c
29
cli/repl.c
@ -12,6 +12,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
// FIXME: use fgetc char by char till reach a new line.
|
// FIXME: use fgetc char by char till reach a new line.
|
||||||
|
// TODO: Will need refactoring to use a byte buffer.
|
||||||
//
|
//
|
||||||
// Read a line from stdin and returns it without the line ending. Accepting
|
// Read a line from stdin and returns it without the line ending. Accepting
|
||||||
// an optional argument [length] (could be NULL). Note that the returned string
|
// an optional argument [length] (could be NULL). Note that the returned string
|
||||||
@ -29,6 +30,19 @@ const char* read_line(uint32_t* length) {
|
|||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reads a line one character at a time and stop reading when we hit the
|
||||||
|
// EOF or a new line. The buffer resizes itself when count == capacity.
|
||||||
|
static void readLine(ByteBuffer* buff) {
|
||||||
|
do {
|
||||||
|
char c = fgetc(stdin);
|
||||||
|
if (c == EOF || c == '\n') break;
|
||||||
|
|
||||||
|
byteBufferWrite(buff, (uint8_t)c);
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
byteBufferWrite(buff, '\0');
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if the string is empty, used to check if the input line is
|
// Returns true if the string is empty, used to check if the input line is
|
||||||
// empty to skip compilation of empty string.
|
// empty to skip compilation of empty string.
|
||||||
static inline bool is_str_empty(const char* line) {
|
static inline bool is_str_empty(const char* line) {
|
||||||
@ -57,6 +71,10 @@ int repl(PKVM* vm, const PkCompileOptions* options) {
|
|||||||
ByteBuffer lines;
|
ByteBuffer lines;
|
||||||
byteBufferInit(&lines);
|
byteBufferInit(&lines);
|
||||||
|
|
||||||
|
// A buffer to store a line read from stdin.
|
||||||
|
ByteBuffer line;
|
||||||
|
byteBufferInit(&line);
|
||||||
|
|
||||||
// Will be set to true if the compilation failed with unexpected EOF to add
|
// Will be set to true if the compilation failed with unexpected EOF to add
|
||||||
// more lines to the [lines] buffer.
|
// more lines to the [lines] buffer.
|
||||||
bool need_more_lines = false;
|
bool need_more_lines = false;
|
||||||
@ -72,20 +90,19 @@ int repl(PKVM* vm, const PkCompileOptions* options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read a line from stdin and add the line to the lines buffer.
|
// Read a line from stdin and add the line to the lines buffer.
|
||||||
uint32_t length = 0;
|
readLine(&line);
|
||||||
const char* line = read_line(&length);
|
bool is_empty = is_str_empty((const char*)line.data);
|
||||||
bool is_empty = is_str_empty(line);
|
|
||||||
|
|
||||||
// If the line is empty, we don't have to compile it.
|
// If the line is empty, we don't have to compile it.
|
||||||
if (is_empty && !need_more_lines) {
|
if (is_empty && !need_more_lines) {
|
||||||
free((void*)line);
|
byteBufferClear(&line);
|
||||||
ASSERT(lines.count == 0, OOPS);
|
ASSERT(lines.count == 0, OOPS);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lines.count != 0) byteBufferWrite(&lines, '\n');
|
if (lines.count != 0) byteBufferWrite(&lines, '\n');
|
||||||
byteBufferAddString(&lines, line, length);
|
byteBufferAddString(&lines, (const char*)line.data, line.count - 1);
|
||||||
free((void*)line);
|
byteBufferClear(&line);
|
||||||
byteBufferWrite(&lines, '\0');
|
byteBufferWrite(&lines, '\0');
|
||||||
|
|
||||||
// Compile the buffer to the module.
|
// Compile the buffer to the module.
|
||||||
|
Loading…
Reference in New Issue
Block a user