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" #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.