Browse files

[wip] repl somewhat functional

  • Loading branch information...
1 parent 4374493 commit 91cbef1fb46ba8ba07b3d817c347f7b0935043af @bmeck committed Mar 29, 2012
Showing with 119 additions and 0 deletions.
  1. +1 −0 Makefile
  2. +34 −0 examples/repl.can
  3. +30 −0 src/cio.cc
  4. +1 −0 src/luv.cc
  5. +44 −0 src/luv_tty.cc
  6. +9 −0 src/luv_tty.h
View
1 Makefile
@@ -27,6 +27,7 @@ LIBS=build/main.o \
build/luv_handle.o \
build/luv_stream.o \
build/luv_tcp.o \
+ build/luv_tty.o \
build/luv_timer.o \
build/net.cc
View
34 examples/repl.can
@@ -0,0 +1,34 @@
+prettyPrint = global.prettyPrint
+require = global.require
+eval = global.eval
+
+subenv = {
+ require: require,
+ eval: eval
+}
+
+str = ''
+handleKeyStroke = (c) {
+ if (c == '\n' || c == '\r') {
+ prettyPrint(str)
+ value = eval(str)
+ err = global.lastError()
+ if (err != nil) {
+ prettyPrint(err)
+ return
+ }
+ prettyPrint(value)
+ str = ''
+ if (global)
+ return
+ }
+ str = str + c
+ stdout:write(1, c)
+}
+
+stdin = require('tty').create(0)
+stdout = require('tty').create(1)
+stdin:readStart(printOut(length, c) {
+ handleKeyStroke(c)
+})
+stdin:setMode(true)
View
30 src/cio.cc
@@ -7,6 +7,7 @@
#include "lhttp_parser.h" // http_parser_module
#include "luv_base.h" // uv_base_module
#include "luv_tcp.h" // uv_tcp_module
+#include "luv_tty.h" // uv_tty_module
#include "luv_timer.h" // uv_timer_module
#include <assert.h> // assert
@@ -137,6 +138,21 @@ static Value* PrettyPrint(uint32_t argc, Value* argv[]) {
return Nil::New();
}
+static Value* Eval(uint32_t argc, Value* argv[]) {
+ assert(argc > 0);
+ Function* fn = Function::New(argv[0]->ToString()->Value());
+ if (fn == NULL) {
+ return Nil::New();
+ }
+ if (argc > 1 && argv[1]->Is<Object>()) {
+ fn->SetContext((Object*)argv[1]);
+ }
+ else {
+ fn->SetContext(cio_global_context());
+ }
+ return fn->Call(0, NULL);
+}
+
static Value* Exit(uint32_t argc, Value* argv[]) {
int status = 0;
if (argc) {
@@ -146,6 +162,17 @@ static Value* Exit(uint32_t argc, Value* argv[]) {
return Nil::New();
}
+static Value* LastError(uint32_t argc, Value* argv[]) {
+ Isolate* iso = Isolate::GetCurrent();
+ if (!iso->HasError()) return Nil::New();
+ Error* existing = iso->GetError();
+ Object* err = new Object();
+ err->Set("filename", String::New(existing->filename));
+ err->Set("line", Number::NewIntegral(existing->line));
+ err->Set("message", String::New(existing->message));
+ return err;
+}
+
static Value* LoadBuiltin(uint32_t argc, Value* argv[]) {
assert(argc == 1);
const char* name = argv[0]->As<String>()->Value();
@@ -157,6 +184,7 @@ static Value* LoadBuiltin(uint32_t argc, Value* argv[]) {
if (0 == strcmp(name, "uv")) return uv_base_module();
if (0 == strcmp(name, "timer")) return uv_timer_module();
if (0 == strcmp(name, "tcp")) return uv_tcp_module();
+ if (0 == strcmp(name, "tty")) return uv_tty_module();
if (0 == strcmp(name, "http_parser")) return http_parser_module();
return Nil::New();
}
@@ -167,6 +195,8 @@ Object* cio_global_context() {
global.Wrap(Object::New());
global->Set("print", Function::New(Print));
global->Set("prettyPrint", Function::New(PrettyPrint));
+ global->Set("eval", Function::New(Eval));
+ global->Set("lastError", Function::New(LastError));
global->Set("exit", Function::New(Exit));
global->Set("require", Function::New(LoadBuiltin));
return *global;
View
1 src/luv.cc
@@ -9,6 +9,7 @@ template uv_handle_t* UVData::ObjectTo<uv_handle_t>(candor::Object* obj);
template uv_timer_t* UVData::ObjectTo<uv_timer_t>(candor::Object* obj);
template uv_stream_t* UVData::ObjectTo<uv_stream_t>(candor::Object* obj);
template uv_tcp_t* UVData::ObjectTo<uv_tcp_t>(candor::Object* obj);
+template uv_tty_t* UVData::ObjectTo<uv_tty_t>(candor::Object* obj);
UVData::UVData(size_t size, Object* prototype) {
// Create a new data object
View
44 src/luv_tty.cc
@@ -0,0 +1,44 @@
+#include "luv_stream.h" // uv_stream_prototype
+#include "luv_tty.h"
+
+#include "luv.h"
+#include "candor.h"
+#include "uv.h"
+
+#include <assert.h> // assert
+
+using namespace candor;
+
+static Value* luv_create_tty(uint32_t argc, Value* argv[]) {
+ assert(argc > 0);
+ int fd = argv[0]->ToNumber()->IntegralValue();
+ UVData* data = new UVData(sizeof(uv_tty_t), uv_tty_prototype());
+ uv_tty_init(uv_default_loop(), (uv_tty_t*)data->handle, fd, argc > 1 ? argv[1]->ToBoolean()->IsTrue() : fd == 0);
+ return *data->obj;
+}
+
+static Value* luv_tty_set_mode(uint32_t argc, Value* argv[]) {
+ assert(argc == 2);
+ Object* obj = argv[0]->As<Object>();
+ uv_tty_t* handle = UVData::ObjectTo<uv_tty_t>(obj);
+ int status = uv_tty_set_mode(handle, argv[1]->As<Boolean>()->IsTrue());
+ return Number::NewIntegral(status);
+}
+
+static Handle<Object> module;
+Object* uv_tty_module() {
+ if (!module.IsEmpty()) return *module;
+ module.Wrap(Object::New());
+ module->Set("create", Function::New(luv_create_tty));
+ return *module;
+}
+
+static Handle<Object> prototype;
+Object* uv_tty_prototype() {
+ if (!prototype.IsEmpty()) return *prototype;
+ prototype.Wrap(uv_stream_prototype()->Clone());
+ prototype->Set("setMode", Function::New(luv_tty_set_mode));
+ return *prototype;
+}
+
+
View
9 src/luv_tty.h
@@ -0,0 +1,9 @@
+#ifndef LUV_TTY_H
+#define LUV_TTY_H
+
+#include "candor.h"
+
+candor::Object* uv_tty_module();
+candor::Object* uv_tty_prototype();
+
+#endif

0 comments on commit 91cbef1

Please sign in to comment.