|
@@ -3,7 +3,9 @@
|
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
#include <sys/ioctl.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
|
+#include <termios.h>
|
|
|
#include <threads.h>
|
|
#include <threads.h>
|
|
|
|
|
+#include <unistd.h>
|
|
|
|
|
|
|
|
#include "Memory.h"
|
|
#include "Memory.h"
|
|
|
|
|
|
|
@@ -12,7 +14,8 @@
|
|
|
return false
|
|
return false
|
|
|
|
|
|
|
|
static u32 seed = 0;
|
|
static u32 seed = 0;
|
|
|
-static bool printNewline = true;
|
|
|
|
|
|
|
+static bool rawMode = false;
|
|
|
|
|
+static struct termios originalTerminal;
|
|
|
|
|
|
|
|
static bool sfPrint(Code* c, Value* r, Value* vs, i32 n) {
|
|
static bool sfPrint(Code* c, Value* r, Value* vs, i32 n) {
|
|
|
for(i32 i = 0; i < n; i++) {
|
|
for(i32 i = 0; i < n; i++) {
|
|
@@ -25,15 +28,13 @@ static bool sfPrint(Code* c, Value* r, Value* vs, i32 n) {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if(printNewline) {
|
|
|
|
|
- putchar('\n');
|
|
|
|
|
- }
|
|
|
|
|
RETURN_INT(0);
|
|
RETURN_INT(0);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static bool sfSetPrintNewline(Code*, Value* r, Value* vs, i32) {
|
|
|
|
|
- printNewline = vs[0].data;
|
|
|
|
|
- RETURN_INT(0);
|
|
|
|
|
|
|
+static bool sfPrintLine(Code* c, Value* r, Value* vs, i32 n) {
|
|
|
|
|
+ bool b = sfPrint(c, r, vs, n);
|
|
|
|
|
+ putchar('\n');
|
|
|
|
|
+ return b;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#define ESC "\33["
|
|
#define ESC "\33["
|
|
@@ -155,6 +156,48 @@ static bool sfGetAllocations(Code* c, Value* r, Value*, i32) {
|
|
|
RETURN_INT(counter);
|
|
RETURN_INT(counter);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static bool sfEnterRawTerminal(Code* c, Value* r, Value*, i32) {
|
|
|
|
|
+ if(rawMode) {
|
|
|
|
|
+ RETURN_INT(0);
|
|
|
|
|
+ }
|
|
|
|
|
+ if(tcgetattr(STDIN_FILENO, &originalTerminal)) {
|
|
|
|
|
+ SET_ERROR("Cannot safe current terminal mode");
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ struct termios raw = originalTerminal;
|
|
|
|
|
+ raw.c_iflag &= ~(tcflag_t)(ICRNL | IXON);
|
|
|
|
|
+ raw.c_lflag &= ~(tcflag_t)(ECHO | ICANON | IEXTEN | ISIG);
|
|
|
|
|
+ raw.c_cc[VMIN] = 0;
|
|
|
|
|
+ raw.c_cc[VTIME] = 0;
|
|
|
|
|
+ if(tcsetattr(STDIN_FILENO, TCSANOW, &raw)) {
|
|
|
|
|
+ SET_ERROR("Cannot enter raw terminal mode");
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ RETURN_INT(0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static bool sfLeaveRawTerminal(Code* c, Value* r, Value*, i32) {
|
|
|
|
|
+ if(!rawMode) {
|
|
|
|
|
+ RETURN_INT(0);
|
|
|
|
|
+ }
|
|
|
|
|
+ if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &originalTerminal)) {
|
|
|
|
|
+ SET_ERROR("Cannot leave raw terminal mode");
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ RETURN_INT(0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static bool sfReadChar(Code*, Value* r, Value*, i32) {
|
|
|
|
|
+ u8 ch = 0;
|
|
|
|
|
+ ssize_t bytes = read(STDIN_FILENO, &ch, 1);
|
|
|
|
|
+ RETURN_INT(bytes <= 0 ? '\0' : ch);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static bool sfFlush(Code*, Value* r, Value*, i32) {
|
|
|
|
|
+ fflush(stdout);
|
|
|
|
|
+ RETURN_INT(0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
typedef struct {
|
|
typedef struct {
|
|
|
SystemFunction function;
|
|
SystemFunction function;
|
|
|
i32 arguments;
|
|
i32 arguments;
|
|
@@ -163,7 +206,7 @@ typedef struct {
|
|
|
|
|
|
|
|
static FunctionEntry systemFunctions[] = {
|
|
static FunctionEntry systemFunctions[] = {
|
|
|
{sfPrint, -1, "print"},
|
|
{sfPrint, -1, "print"},
|
|
|
- {sfSetPrintNewline, 1, "setPrintNewline"},
|
|
|
|
|
|
|
+ {sfPrintLine, -1, "printLine"},
|
|
|
{sfClear, 0, "clear"},
|
|
{sfClear, 0, "clear"},
|
|
|
{sfSleep, 2, "sleep"},
|
|
{sfSleep, 2, "sleep"},
|
|
|
{sfGetWidth, 0, "getWidth"},
|
|
{sfGetWidth, 0, "getWidth"},
|
|
@@ -179,6 +222,10 @@ static FunctionEntry systemFunctions[] = {
|
|
|
{sfRandom, 2, "random"},
|
|
{sfRandom, 2, "random"},
|
|
|
{sfArray, 1, "array"},
|
|
{sfArray, 1, "array"},
|
|
|
{sfGetAllocations, 0, "getAllocations"},
|
|
{sfGetAllocations, 0, "getAllocations"},
|
|
|
|
|
+ {sfEnterRawTerminal, 0, "enterRawTerminal"},
|
|
|
|
|
+ {sfLeaveRawTerminal, 0, "leaveRawTerminal"},
|
|
|
|
|
+ {sfReadChar, 0, "readChar"},
|
|
|
|
|
+ {sfFlush, 0, "flush"},
|
|
|
};
|
|
};
|
|
|
static constexpr i32 amount = sizeof(systemFunctions) / sizeof(FunctionEntry);
|
|
static constexpr i32 amount = sizeof(systemFunctions) / sizeof(FunctionEntry);
|
|
|
|
|
|