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:
Thakee Nathees 2021-06-16 17:30:16 +05:30 committed by GitHub
commit 2b92758b83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -12,6 +12,7 @@
#include "utils.h"
// 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
// 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;
}
// 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
// empty to skip compilation of empty string.
static inline bool is_str_empty(const char* line) {
@ -57,6 +71,10 @@ int repl(PKVM* vm, const PkCompileOptions* options) {
ByteBuffer 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
// more lines to the [lines] buffer.
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.
uint32_t length = 0;
const char* line = read_line(&length);
bool is_empty = is_str_empty(line);
readLine(&line);
bool is_empty = is_str_empty((const char*)line.data);
// If the line is empty, we don't have to compile it.
if (is_empty && !need_more_lines) {
free((void*)line);
byteBufferClear(&line);
ASSERT(lines.count == 0, OOPS);
continue;
}
if (lines.count != 0) byteBufferWrite(&lines, '\n');
byteBufferAddString(&lines, line, length);
free((void*)line);
byteBufferAddString(&lines, (const char*)line.data, line.count - 1);
byteBufferClear(&line);
byteBufferWrite(&lines, '\0');
// Compile the buffer to the module.