First commit
This commit is contained in:
189
src/runtime_methods/console.cpp
Normal file
189
src/runtime_methods/console.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
#include "CrossLang.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#if defined(GEKKO)
|
||||
#undef CROSSLANG_ENABLE_TERMIOS
|
||||
#endif
|
||||
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
#include <termios.h>
|
||||
#endif
|
||||
namespace Tesses::CrossLang {
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios orig_termios;
|
||||
static void disableRawMode()
|
||||
{
|
||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
|
||||
}
|
||||
#endif
|
||||
TObject Console_getEcho(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(STDIN_FILENO, &raw);
|
||||
return (raw.c_lflag & ECHO) > 0;
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
TObject Console_setEcho(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
||||
{
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(STDIN_FILENO, &raw);
|
||||
if(cooked)
|
||||
{
|
||||
raw.c_lflag |= ECHO;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw.c_lflag &= ~(ECHO);
|
||||
}
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
|
||||
|
||||
#endif
|
||||
return cooked;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getCanonical(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(STDIN_FILENO, &raw);
|
||||
return (raw.c_lflag & ICANON) > 0;
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
TObject Console_setCanonical(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
||||
{
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(STDIN_FILENO, &raw);
|
||||
if(cooked)
|
||||
{
|
||||
raw.c_lflag |= ICANON;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw.c_lflag &= ~(ICANON);
|
||||
}
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
|
||||
|
||||
#endif
|
||||
return cooked;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getSignals(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(STDIN_FILENO, &raw);
|
||||
return (raw.c_lflag & ISIG) > 0;
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
TObject Console_setSignals(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
||||
{
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(STDIN_FILENO, &raw);
|
||||
if(cooked)
|
||||
{
|
||||
raw.c_lflag |= ISIG;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw.c_lflag &= ~(ISIG);
|
||||
}
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
|
||||
|
||||
#endif
|
||||
return cooked;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
TObject Console_Read(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
uint8_t byte;
|
||||
std::cin.read((char*)&byte,1);
|
||||
return std::cin.eof() ? (int64_t)-1 : (int64_t)byte;
|
||||
}
|
||||
TObject Console_ReadLine(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string str;
|
||||
std::getline(std::cin,str);
|
||||
return str;
|
||||
}
|
||||
TObject Console_Write(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
return Undefined();
|
||||
}
|
||||
std::cout << ToString(ls.GetGC(),args[0]);
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_Fatal(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
std::cout << "FATAL: <NO MESSAGE>" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
std::cout << "FATAL: " << ToString(ls.GetGC(),args[0]) << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
TObject Console_WriteLine(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
std::cout << "\n";
|
||||
return Undefined();
|
||||
}
|
||||
std::cout << ToString(ls.GetGC(),args[0]) << "\n";
|
||||
return Undefined();
|
||||
}
|
||||
void TStd::RegisterConsole(GC* gc,TRootEnvironment* env)
|
||||
{
|
||||
env->permissions.canRegisterConsole=true;
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
tcgetattr(STDIN_FILENO, &orig_termios);
|
||||
atexit(disableRawMode);
|
||||
#endif
|
||||
GCList ls(gc);
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc,"getEcho","Get whether terminal is echoing characters read",{},Console_getEcho);
|
||||
dict->DeclareFunction(gc,"setEcho","Set whether terminal is echoing characters read",{"flag"},Console_setEcho);
|
||||
dict->DeclareFunction(gc,"getCanonical","Get whether terminal is buffering line by line (true) or byte by byte (false)",{},Console_getCanonical);
|
||||
dict->DeclareFunction(gc,"setCanonical","Set whether terminal is buffering line by line (true) or byte by byte (false)",{"flag"},Console_setCanonical);
|
||||
dict->DeclareFunction(gc,"getSignals","Get whether terminal is sending signals for CTRL+C (true) or via read (false)",{},Console_getSignals);
|
||||
dict->DeclareFunction(gc,"setSignals","Set whether terminal is sending signals for CTRL+C (true) or via read (false)",{"flag"},Console_setSignals);
|
||||
|
||||
dict->DeclareFunction(gc,"Read", "Reads a byte from stdin",{},Console_Read);
|
||||
dict->DeclareFunction(gc,"ReadLine","Reads line from stdin",{},Console_ReadLine);
|
||||
dict->DeclareFunction(gc,"Write","Write text \"text\" to stdout",{"text"},Console_Write);
|
||||
dict->DeclareFunction(gc,"WriteLine","Write text \"text\" to stdout with new line",{"text"},Console_WriteLine);
|
||||
dict->DeclareFunction(gc,"Fatal","Stop the program with an optional error message",{"$text"},Console_Fatal);
|
||||
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Console", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user