Permalink
Browse files

- better string literal

- json decode
- change directory structure
  • Loading branch information...
1 parent 9e4eb89 commit c19065555080733c8547c00d14ba650f2082102d @tokuhirom committed Mar 20, 2012
Showing with 108 additions and 10,345 deletions.
  1. +10 −10 SConstruct
  2. +3 −3 ext/JSON/SConstruct
  3. +37 −8 ext/JSON/json.cc
  4. +18 −0 ext/JSON/t/decode.tra
  5. +0 −321 src/builtin.cc
  6. +0 −12 src/builtin.h
  7. +0 −1,488 src/compiler.cc
  8. +0 −162 src/compiler.h
  9. +0 −66 src/disasm.cc
  10. +0 −18 src/disasm.h
  11. +0 −51 src/frame.cc
  12. +0 −119 src/frame.h
  13. +0 −104 src/inspector.cc
  14. +0 −29 src/inspector.h
  15. +0 −858 src/lempar.c
  16. +0 −128 src/lexer.h
  17. +0 −613 src/lexer.re
  18. +0 −169 src/main.cc
  19. +0 −82 src/memorypool.h
  20. +0 −44 src/node.cc
  21. +0 −248 src/node.h
  22. +0 −134 src/nodes.gen.pl
  23. +0 −31 src/object.cc
  24. +0 −40 src/object.h
  25. +0 −167 src/object/array.cc
  26. +0 −24 src/object/bytes.cc
  27. +0 −24 src/object/caller.cc
  28. +0 −63 src/object/code.cc
  29. +0 −83 src/object/dir.cc
  30. +0 −20 src/object/dynaloader.cc
  31. +0 −41 src/object/env.cc
  32. +0 −103 src/object/file.cc
  33. +0 −57 src/object/internals.cc
  34. +0 −72 src/object/metaclass.cc
  35. +0 −65 src/object/object.cc
  36. +0 −54 src/object/regexp.cc
  37. +0 −296 src/object/socket.cc
  38. +0 −7 src/object/stat.cc
  39. +0 −64 src/object/str.cc
  40. +0 −24 src/object/symbol.cc
  41. +0 −152 src/object/time.cc
  42. +0 −3 src/op.cc
  43. +0 −51 src/op.h
  44. +0 −67 src/op_array.h
  45. +0 −248 src/operator.cc
  46. +0 −33 src/operator.h
  47. +0 −46 src/package.cc
  48. +0 −54 src/package.h
  49. +0 −34 src/package_map.cc
  50. +0 −35 src/package_map.h
  51. +0 −49 src/parser.class.h
  52. +0 −645 src/parser.yy
  53. +0 −60 src/peek.cc
  54. +0 −21 src/peek.h
  55. +0 −42 src/prim.h
  56. +0 −94 src/shared_ptr.h
  57. +0 −27 src/symbol_table.cc
  58. +0 −38 src/symbol_table.h
  59. +0 −65 src/symbols.gen.pl
  60. +0 −35 src/token.gen.pl
  61. +0 −10 src/tora-ext.h
  62. +0 −54 src/tora.h
  63. +0 −34 src/util.cc
  64. +0 −23 src/util.h
  65. +0 −208 src/value.cc
  66. +0 −103 src/value.h
  67. +0 −52 src/value/array.cc
  68. +0 −59 src/value/array.h
  69. +0 −6 src/value/bool.cc
  70. +0 −34 src/value/bool.h
  71. +0 −11 src/value/bytes.cc
  72. +0 −34 src/value/bytes.h
  73. +0 −32 src/value/code.cc
  74. +0 −64 src/value/code.h
  75. +0 −18 src/value/double.h
  76. +0 −25 src/value/exception.cc
  77. +0 −61 src/value/exception.h
  78. +0 −45 src/value/file.h
  79. +0 −4 src/value/hash.cc
  80. +0 −73 src/value/hash.h
  81. +0 −5 src/value/int.cc
  82. +0 −35 src/value/int.h
  83. +0 −167 src/value/object.cc
  84. +0 −35 src/value/object.h
  85. +0 −29 src/value/pointer.h
  86. +0 −9 src/value/range.cc
  87. +0 −30 src/value/range.h
  88. +0 −4 src/value/regexp.cc
  89. +0 −96 src/value/regexp.h
  90. +0 −33 src/value/str.cc
  91. +0 −34 src/value/str.h
  92. +0 −23 src/value/symbol.h
  93. +0 −28 src/value/tuple.h
  94. +0 −19 src/value/undef.h
  95. +0 −678 src/vm.cc
  96. +0 −178 src/vm.gen.pl
  97. +0 −196 src/vm.h
  98. +0 −80 src/vm.ops.inc.h
  99. +18 −0 tests/test_hexchar2int.cc
  100. +6 −6 tests/test_inspector.cc
  101. +10 −3 tests/test_lexer.cc
  102. +3 −3 tests/test_package.cc
  103. +1 −1 tests/test_split_package.cc
  104. +1 −1 tests/test_value.cc
  105. +1 −1 tools/lemon/lemon.c
View
20 SConstruct
@@ -75,7 +75,7 @@ re2files = [
'vendor/re2/util/stringpiece.cc',
]
libfiles = [
- "src/" + x for x in Split('''
+ "tora/" + x for x in Split('''
parser.cc value.cc compiler.cc
node.cc op.cc vm.cc util.cc
symbol_table.cc package_map.cc frame.cc package.cc operator.cc
@@ -131,24 +131,24 @@ if 'op' in COMMAND_LINE_TARGETS:
########
# main programs
-env.Command(['src/nodes.gen.h', 'src/nodes.gen.cc'], 'src/nodes.gen.pl', 'perl src/nodes.gen.pl > src/nodes.gen.h');
-env.Command(['src/token.gen.cc', 'src/token.gen.h'], ['src/token.gen.pl', 'src/parser.h'], 'perl src/token.gen.pl');
-env.Command(['src/lexer.gen.cc'], 'src/lexer.re', 're2c src/lexer.re > src/lexer.gen.cc');
-env.Command(['src/vm.gen.cc', 'src/ops.gen.h', 'src/ops.gen.cc'], ['src/vm.gen.pl', 'vm.inc'], 'perl -I misc/Text-MicroTemplate/ src/vm.gen.pl > src/vm.gen.cc');
-env.Command(['src/symbols.gen.cc', 'src/symbols.gen.h'], ['src/symbols.gen.pl'], 'perl -I misc/Text-MicroTemplate/ src/symbols.gen.pl');
-t = env.Command(['src/parser.h', 'src/parser.cc'], ['tools/lemon/lemon', 'src/parser.yy', 'src/lempar.c'], './tools/lemon/lemon src/parser.yy');
-Clean(t, 'src/parser.out')
+env.Command(['tora/nodes.gen.h', 'tora/nodes.gen.cc'], 'tora/nodes.gen.pl', 'perl tora/nodes.gen.pl > tora/nodes.gen.h');
+env.Command(['tora/token.gen.cc', 'tora/token.gen.h'], ['tora/token.gen.pl', 'tora/parser.h'], 'perl tora/token.gen.pl');
+env.Command(['tora/lexer.gen.cc'], 'tora/lexer.re', 're2c tora/lexer.re > tora/lexer.gen.cc');
+env.Command(['tora/vm.gen.cc', 'tora/ops.gen.h', 'tora/ops.gen.cc'], ['tora/vm.gen.pl', 'vm.inc'], 'perl -I misc/Text-MicroTemplate/ tora/vm.gen.pl > tora/vm.gen.cc');
+env.Command(['tora/symbols.gen.cc', 'tora/symbols.gen.h'], ['tora/symbols.gen.pl'], 'perl -I misc/Text-MicroTemplate/ tora/symbols.gen.pl');
+t = env.Command(['tora/parser.h', 'tora/parser.cc'], ['tools/lemon/lemon', 'tora/parser.yy', 'tora/lempar.c'], './tools/lemon/lemon tora/parser.yy');
+Clean(t, 'tora/parser.out')
libre2 = re2_env.Library('re2', re2files)
# config.h
-with open('src/config.h', 'w') as f:
+with open('tora/config.h', 'w') as f:
f.write("#pragma once\n")
f.write('#define TORA_CCFLAGS "' + ' '.join(env.get('CCFLAGS')) + "\"\n")
f.write('#define TORA_PREFIX "' + env.get('PREFIX') + "\"\n")
f.write('#define TORA_VERSION_STR "' + TORA_VERSION_STR + "\"\n")
tora = env.Program('bin/tora', [
- ['src/main.cc'],
+ ['tora/main.cc'],
libfiles,
libre2
])
View
6 ext/JSON/SConstruct
@@ -2,7 +2,7 @@ import os
env = Environment(
CCFLAGS=[
- '-I../../src/',
+ '-I../../tora/',
'-I../../vendor/boost_1_49_0/',
'-g',
'-DNDEBUG'
@@ -29,7 +29,7 @@ else:
LINKFLAGS=['-Wl,-Bsymbolic'],
)
-shlib = env.SharedLibrary("lib/libJSON.so", ['json.cc'])
+shlib = env.SharedLibrary("lib/JSON.so", ['json.cc'], SHLIBPREFIX='')
Default(shlib)
-env.Command('test', shlib, '../../tora -I lib -I ../../lib/ t/json.tra')
+env.Command('test', shlib, '../../bin/tora -I lib -I ../../lib/ t/json.tra && ../../bin/tora -I lib -I ../../lib/ t/decode.tra')
View
45 ext/JSON/json.cc
@@ -1,6 +1,6 @@
#include "json.h"
-#include <tora.h>
+#include "tora.h"
#include <vm.h>
#include <value/array.h>
#include <value/hash.h>
@@ -61,7 +61,7 @@ static Value* json_encode2(std::string & buf, Value *v) {
break;
}
default:
- return new ExceptionValue("%s is not JSON serializable.", v->type_str());
+ throw new ExceptionValue("%s is not JSON serializable.", v->type_str());
}
return NULL;
}
@@ -73,11 +73,33 @@ static Value* json_encode2(std::string & buf, Value *v) {
*/
static SharedPtr<Value> json_encode(VM *vm, Value *klass, Value* v) {
std::string buf;
- Value * exception = json_encode2(buf, v);
- if (exception) {
- return exception;
+ json_encode2(buf, v);
+ return new StrValue(buf);
+}
+
+static SharedPtr<Value> json_decode2(picojson::value & v) {
+ if (v.is<double>()) {
+ return new DoubleValue(v.get<double>());
+ } else if (v.is<bool>()) {
+ return new BoolValue(v.get<bool>());
+ } else if (v.is<std::string>()) {
+ return new StrValue(v.get<std::string>());
+ } else if (v.is<picojson::array>()) {
+ picojson::array & ary = v.get<picojson::array>();
+ SharedPtr<ArrayValue> av = new ArrayValue();
+ for (auto iter: ary) {
+ av->push(json_decode2(iter));
+ }
+ return av;
+ } else if (v.is<picojson::object>()) {
+ picojson::object & obj = v.get<picojson::object>();
+ SharedPtr<HashValue> hv = new HashValue();
+ for (auto iter: obj) {
+ hv->set(iter.first, json_decode2(iter.second));
+ }
+ return hv;
} else {
- return new StrValue(buf);
+ TODO();
}
}
@@ -86,8 +108,15 @@ static SharedPtr<Value> json_encode(VM *vm, Value *klass, Value* v) {
*
* Decode $json to Hash|Array.
*/
-static SharedPtr<Value> json_decode(VM *vm, Value *klass, Value* v) {
- TODO();
+static SharedPtr<Value> json_decode(VM *vm, Value *klass, Value* json_v) {
+ StrValue * json_sv = static_cast<StrValue*>(json_v);
+ picojson::value v;
+ const char * in = json_sv->str_value.c_str();
+ std::string err = picojson::parse(v, in, in + json_sv->str_value.size());
+ if (!err.empty()) {
+ throw new ExceptionValue(err);
+ }
+ return json_decode2(v);
}
extern "C" {
View
18 ext/JSON/t/decode.tra
@@ -0,0 +1,18 @@
+use Test::More *;
+use JSON;
+
+is(JSON.decode('true'), true);
+is(JSON.decode('false'), false);
+is(JSON.decode('90.5'), 90.5);
+is(JSON.decode("\"hello\""), 'hello');
+is(JSON.decode("\"\\\"\\\\\\/\\b\\f\\n\\r\\t\""), "\"\\/\b\f\n\r\t");
+is(JSON.decode("\"\\u0061\\u30af\\u30ea\\u30b9\""), "a\xe3\x82\xaf\xe3\x83\xaa\xe3\x82\xb9");
+is(JSON.decode("\"\\ud840\\udc0b\""), "\xf0\xa0\x80\x8b");
+# is(typeof(JSON.decode('{}')), 'Hash');
+
+is(JSON.decode("[]").tora(), [].tora);
+is(JSON.decode("{}").tora(), {}.tora);
+is(JSON.decode("{\"foo\":3}").tora(), {foo => 3}.tora);
+is(JSON.decode("[1,3,\"hoge\"]").tora(), [1,3,'hoge'].tora);
+
+done_testing;
View
321 src/builtin.cc
@@ -1,321 +0,0 @@
-#include <sys/types.h>
-#include <dirent.h>
-
-#include "builtin.h"
-#include "vm.h"
-#include "value.h"
-#include "frame.h"
-#include "value/file.h"
-#include "value/object.h"
-#include "value/pointer.h"
-#include "value/array.h"
-#include "value/str.h"
-#include "value/exception.h"
-#include "value.h"
-#include "object.h"
-#include "inspector.h"
-
-using namespace tora;
-
-static SharedPtr<Value> builtin_exit(VM *vm, Value* v) {
- exit(v->to_int());
-}
-
-static SharedPtr<Value> builtin_p(VM *vm, Value* arg1) {
- Inspector ins(vm);
- assert(vm);
- assert(vm->symbol_table);
- printf("%s\n", ins.inspect(arg1).c_str());
- return UndefValue::instance();
-}
-
-static SharedPtr<Value> builtin_say(VM *vm, const std::vector<SharedPtr<Value>> & args) {
- auto iter = args.begin();
- for (; iter!=args.end(); iter++) {
- SharedPtr<Value> v(*iter);
- SharedPtr<Value> s(v->to_s());
- // printf("%s\n", s->upcast<StrValue>()->str_value.c_str());
- fwrite(s->upcast<StrValue>()->str_value.c_str(), sizeof(char), s->upcast<StrValue>()->str_value.size(), stdout);
- fputc('\n', stdout);
- }
- return UndefValue::instance();
-}
-
-static SharedPtr<Value> builtin_package(VM *vm) {
- return new StrValue(vm->package_name());
-}
-
-static SharedPtr<Value> builtin_typeof(VM *vm, Value *v) {
- return new StrValue(v->type_str());
-}
-
-/**
- * open(Str $fname) : FileHandle
- * open(Str $fname, Str $mode) : FileHandle
- */
-static SharedPtr<Value> builtin_open(VM *vm, const std::vector<SharedPtr<Value>> & args) {
- if (args.size() != 1 && args.size() != 2) {
- return new ExceptionValue("Invalid argument count for open(): %zd. open() function requires 1 or 2 argument.", args.size());
- }
- return File_open(vm, args.at(0).get(), args.size() == 2 ? args.at(1).get() : NULL);
-}
-
-static SharedPtr<Value> builtin_print(VM *vm, const std::vector<SharedPtr<Value>> & args) {
- auto iter = args.begin();
- for (; iter!=args.end(); iter++) {
- SharedPtr<Value> v(*iter);
- SharedPtr<Value> s(v->to_s());
- printf("%s", s->upcast<StrValue>()->str_value.c_str());
- }
- return UndefValue::instance();
-}
-
-static SharedPtr<Value> builtin_opendir(VM * vm, Value* s) {
- SharedPtr<StrValue> dirname = s->to_s();
- return Dir_new(vm, dirname.get());
-}
-
-/**
- * rand() : Double;
- * rand($n Double) : Double;
- * rand($n Int) : Int;
- *
- * Get a random number.
- *
- * rand() returns [0, 1) in Double value.
- * rand($n :Double) returns [0, $n) in Double value.
- * rand($n :Int) returns [0, $n) in Int value.
- */
-static SharedPtr<Value> builtin_rand(VM *vm, const std::vector<SharedPtr<Value>>& args) {
- // TODO: use std::mt19937 in c++11.
- // in 2012, I use g++ 4.4.3. It does not support uniform_real_distribution
- if (args.size() == 0) {
- boost::uniform_real<double> dist(0.0, 1.0);
- return new DoubleValue(dist(*(vm->myrand)));
- } else if (args.size() == 1) {
- SharedPtr<Value> v = args.at(0);
- if (v->value_type == VALUE_TYPE_DOUBLE) {
- boost::uniform_real<double> dist(0.0, v->upcast<DoubleValue>()->double_value);
- return new DoubleValue(dist(*(vm->myrand)));
- } else if (v->value_type == VALUE_TYPE_INT) {
- boost::uniform_int<int> dist(0, v->upcast<IntValue>()->int_value);
- return new IntValue(dist(*(vm->myrand)));
- } else {
- // support to_int?
- return new ExceptionValue("Invalid arguments for rand() : %s", v->type_str());
- }
- } else {
- return new ExceptionValue("Too many arguments for rand()");
- }
-}
-
-static SharedPtr<Value> builtin_self(VM *vm) {
- return vm->get_self();
-}
-
-/**
- * require("foo/bar.tra")
- */
-static SharedPtr<Value> builtin_require(VM *vm, Value *v) {
- return vm->require(v);
-}
-
-/**
- * my $code = callee() : Code;
- *
- * Returns callee code object.
- * Return undef if it's not in subroutine.
- */
-static SharedPtr<Value> builtin_callee(VM *vm) {
- for (auto iter = vm->frame_stack->rbegin(); iter != vm->frame_stack->rend(); ++iter) {
- if ((*iter)->type == FRAME_TYPE_FUNCTION) {
- FunctionFrame* fframe = (*iter)->upcast<FunctionFrame>();
- return fframe->code;
- }
- }
- return UndefValue::instance();
-}
-
-/**
- * caller(0) : Caller
- * caller() : Array[Caller]
- *
- */
-static SharedPtr<Value> builtin_caller(VM *vm, const std::vector<SharedPtr<Value>>& args) {
- if (args.size() == 0) {
- int skiped_first = false;
- SharedPtr<ArrayValue> av = new ArrayValue();
- for (auto iter = vm->frame_stack->rbegin(); iter != vm->frame_stack->rend(); ++iter) {
- if ((*iter)->type == FRAME_TYPE_FUNCTION) {
- if (skiped_first) {
- FunctionFrame* fframe = (*iter)->upcast<FunctionFrame>();
- SharedPtr<ObjectValue> o = new ObjectValue(vm, vm->symbol_table->get_id("Caller"), fframe->code);
- av->push(o);
- } else {
- skiped_first = true; // skip myself.
- }
- }
- }
- return av.get();
- } else if (args.size() == 1) {
- int seen = 0;
- int need = args.at(0)->to_int();
- for (auto iter = vm->frame_stack->rbegin(); iter != vm->frame_stack->rend(); ++iter) {
- if ((*iter)->type == FRAME_TYPE_FUNCTION) {
- FunctionFrame* fframe = (*iter)->upcast<FunctionFrame>();
- if (seen == need+1) {
- SharedPtr<ObjectValue> o = new ObjectValue(vm, vm->symbol_table->get_id("Caller"), fframe->code);
- return o;
- }
- ++seen;
- }
- }
- return UndefValue::instance();
- } else {
- throw new ExceptionValue("Too many arguments for caller.");
- }
-}
-
-/**
- * Get a current working directory.
- */
-static SharedPtr<Value> builtin_getcwd(VM *vm) {
- // getcwd() is POSIX.1-2001.
- // bad memory allocation??
- char * ptr = new char [MAXPATHLEN+1];
- if (getcwd(ptr, MAXPATHLEN)) {
- std::string ptr_s(ptr);
- delete ptr;
- return new StrValue(ptr_s);
- } else {
- throw new ExceptionValue(errno);
- }
-}
-
-/**
- * Get a current process id.
- */
-static SharedPtr<Value> builtin_getpid(VM *vm) {
- // POSIX.1-2001, 4.3BSD, SVr4.
- return new IntValue(getpid());
-}
-
-/**
- * Get a parent process id.
- */
-static SharedPtr<Value> builtin_getppid(VM *vm) {
- // POSIX.1-2001, 4.3BSD, SVr4.
- return new IntValue(getppid());
-}
-
-static SharedPtr<Value> builtin_abs(VM *vm, Value *v) {
- if (v->value_type == VALUE_TYPE_INT) {
- int i = v->to_int();
- return new IntValue(i < 0 ? -i : i);
- } else if (v->value_type == VALUE_TYPE_DOUBLE) {
- double i = v->to_double();
- return new DoubleValue(i < 0 ? -i : i);
- } else {
- throw new ExceptionValue("abs() is not supported in non numeric value.");
- }
-}
-
-static SharedPtr<Value> builtin_atan2(VM *vm, Value *y, Value *x) {
- return new DoubleValue(atan2(y->to_double(), x->to_double()));
-}
-
-static SharedPtr<Value> builtin_sqrt(VM *vm, Value *v) {
- return new DoubleValue(sqrt(v->to_double()));
-}
-
-static SharedPtr<Value> builtin_cos(VM *vm, Value *v) {
- return new DoubleValue(cos(v->to_double()));
-}
-
-static SharedPtr<Value> builtin_exp(VM *vm, Value *v) {
- return new DoubleValue(exp(v->to_double()));
-}
-
-/**
- * hex(Str $v) : Int
- *
- * hex('0xAF') # => 175
- * hex('aF') # => 175
- */
-static SharedPtr<Value> builtin_hex(VM *vm, Value *v) {
- if (v->value_type != VALUE_TYPE_STR) {
- throw new ExceptionValue("hex() requires string value.");
- }
- const std::string s = v->upcast<StrValue>()->c_str();
- char *endp;
- errno = 0;
- long n = strtol(s.c_str(), &endp, 16);
- if (errno == ERANGE) {
- throw new ExceptionValue(errno);
- }
- if (endp != s.c_str()+s.size()) {
- throw new ExceptionValue("The value is not hexadecimal: %s.", v->upcast<StrValue>()->c_str());
- }
- return new IntValue(n);
-}
-
-static SharedPtr<Value> builtin_oct(VM *vm, Value *v) {
- if (v->value_type != VALUE_TYPE_STR) {
- throw new ExceptionValue("oct() requires string value.");
- }
- const std::string s = v->upcast<StrValue>()->c_str();
- char *endp;
- errno = 0;
- long n = strtol(s.c_str(), &endp, 8);
- if (errno == ERANGE) {
- throw new ExceptionValue(errno);
- }
- if (endp != s.c_str()+s.size()) {
- throw new ExceptionValue("The value is not oct: %s.", v->upcast<StrValue>()->c_str());
- }
- return new IntValue(n);
-}
-
-static SharedPtr<Value> builtin_int(VM *vm, Value *v) {
- return new IntValue(v->to_int());
-}
-
-static SharedPtr<Value> builtin_log(VM *vm, Value *v) {
- return new DoubleValue(log(v->to_double()));
-}
-
-static SharedPtr<Value> builtin_sin(VM *vm, Value *v) {
- return new DoubleValue(sin(v->to_double()));
-}
-
-void tora::Init_builtins(VM *vm) {
- vm->add_builtin_function("p", builtin_p);
- vm->add_builtin_function("exit", builtin_exit);
- vm->add_builtin_function("say", builtin_say);
- vm->add_builtin_function("__PACKAGE__", builtin_package);
- vm->add_builtin_function("typeof", builtin_typeof);
- vm->add_builtin_function("open", builtin_open);
- vm->add_builtin_function("print", builtin_print);
- vm->add_builtin_function("require", builtin_require);
- vm->add_builtin_function("self", builtin_self);
- vm->add_builtin_function("opendir", builtin_opendir);
- vm->add_builtin_function("rand", builtin_rand);
- vm->add_builtin_function("caller", builtin_caller);
- vm->add_builtin_function("callee", builtin_callee);
- vm->add_builtin_function("getcwd", builtin_getcwd);
- vm->add_builtin_function("getpid", builtin_getpid);
- vm->add_builtin_function("getppid", builtin_getppid);
-
- // numeric functions
- vm->add_builtin_function("sqrt", builtin_sqrt);
- vm->add_builtin_function("abs", builtin_abs);
- vm->add_builtin_function("atan2", builtin_atan2);
- vm->add_builtin_function("cos", builtin_cos);
- vm->add_builtin_function("exp", builtin_exp);
- vm->add_builtin_function("hex", builtin_hex);
- vm->add_builtin_function("int", builtin_int);
- vm->add_builtin_function("log", builtin_log);
- vm->add_builtin_function("oct", builtin_oct);
- vm->add_builtin_function("sin", builtin_sin);
-}
-
View
12 src/builtin.h
@@ -1,12 +0,0 @@
-#ifndef TORA_BUILTIN_H_
-#define TORA_BUILTIN_H_
-
-namespace tora {
-
-class VM;
-
-void Init_builtins(VM *vm);
-
-};
-
-#endif // TORA_BUILTIN_H_
View
1,488 src/compiler.cc
@@ -1,1488 +0,0 @@
-#include "compiler.h"
-#include "op_array.h"
-#include "nodes.gen.h"
-#include "node.h"
-#include "value/code.h"
-#include "value/symbol.h"
-#include "value/regexp.h"
-#include "symbol_table.h"
-#include "disasm.h"
-#include <boost/scope_exit.hpp>
-#include <boost/foreach.hpp>
-#include <iostream>
-
-using namespace tora;
-
-class LoopContext {
- Compiler *compiler_;
- bool orig;
-public:
- LoopContext(Compiler *c, bool b) {
- compiler_ = c;
- orig = compiler_->in_loop_context;
- compiler_->in_loop_context = b;
- }
- ~LoopContext() {
- compiler_->in_loop_context = orig;
- }
-};
-
-/**
- * Count up the number of variables declared at this scope.
- */
-static int count_variable_declare(const SharedPtr<Node> &node) {
- if (node->type == NODE_MY) {
- SharedPtr<ListNode>ln = node->upcast<ListNode>();
- return ln->size();
- } else if (node->type == NODE_LOCAL) {
- return 1;
- } else {
- auto iter = node->list->begin();
- int ret = 0;
- for (; iter!=node->list->end(); iter++) {
- if ((*iter).get()) {
- ret += count_variable_declare(*iter);
- }
- }
- return ret;
- }
-}
-
-/**
- * make the node to string node if it's bareword.
- *
- * $foo[word] => $foo['word']
- * $foo[word] = 3 => $foo['word'] = 3
- * {foo => 'bar'} => {'foo' => 'bar'}
- */
-inline static SharedPtr<Node> STRING_IF_BAREWORD(SharedPtr<Node>& node) {
- if (node->type == NODE_FUNCALL && static_cast<FuncallNode*>(node.get())->is_bare) {
- SharedPtr<Node> tmp = node->at(0);
- tmp->type = NODE_STRING;
- return tmp;
- } else {
- return node;
- }
-}
-
-Compiler::Compiler(const SharedPtr<SymbolTable> &symbol_table_, const std::string &filename) : filename_(filename), in_class_context(false) {
- error = 0;
- blocks = new std::vector<SharedPtr<Block>>();
- global_vars = new std::vector<std::string>();
- ops = new OPArray();
- in_try_block = false;
- symbol_table = symbol_table_;
- dump_ops = false;
- package_ = "main";
- closure_vars = new std::vector<std::string>();
- in_loop_context = false;
-}
-Compiler::~Compiler() {
- delete global_vars;
- delete blocks;
- delete closure_vars;
-}
-
-void Compiler::push_op(OP * op) {
- this->ops->push_back(op, this->current_node->lineno);
-}
-
-void Compiler::define_my(SharedPtr<Node> node) {
- SharedPtr<ListNode>ln = node->upcast<ListNode>();
- for (size_t i=0; i < ln->size(); i++) {
- auto target = ln->at(i);
- switch (target->type) {
- case NODE_GETVARIABLE: {
- std::string &name = ln->at(i)->upcast<StrNode>()->str_value;
- this->define_localvar(name);
- push_op(new OP(OP_PUSH_UNDEF));
- this->set_variable(name);
- break;
- }
- case NODE_TUPLE: {
- this->define_my(target);
- break;
- }
- default:
- fail("This is not a variable node: %s\n", target->type_name_str());
- target->dump();
- return;
- }
- }
-}
-
-/**
- * Find local vars level in compilation phase.
- *
- * @return $n > 0 when found var. return -1 when var is not found.
- */
-int tora::Compiler::find_localvar(std::string name, int &level, bool &need_closure, bool &is_arg) {
- DBG("FIND LOCAL VAR %d\n", 0);
- need_closure = false;
- int seen_funcdef = -1;
- for (level = 0; level<this->blocks->size(); level++) {
- SharedPtr<Block> block = this->blocks->at(this->blocks->size()-1-level);
- if (block->type == BLOCK_TYPE_FUNCDEF && seen_funcdef == -1) {
- seen_funcdef = level;
- }
- for (size_t i=0; i<block->vars.size(); i++) {
- if (*(block->vars.at(i)) == name) {
- if (seen_funcdef != -1 && seen_funcdef < level) {
- need_closure = true;
- }
- if (block->type == BLOCK_TYPE_FUNCDEF) {
- is_arg = true;
- } else {
- is_arg = false;
- }
- return i;
- }
- }
- }
- return -1;
-}
-
-void tora::Compiler::init_globals() {
- this->define_global_var("$ARGV");
- this->define_global_var("$ENV");
- this->define_global_var("$LIBPATH");
- this->define_global_var("$REQUIRED");
-}
-
-
-void tora::Compiler::set_variable(std::string &varname) {
- {
- auto pos = varname.rfind("::");
- if (pos != std::string::npos) {
- // package variable $Foo::Bar.
- std::string pkgname = varname.substr(1, pos-1);
- std::string detail = varname.substr(pos+2);
- push_op(new OP(OP_PUSH_IDENTIFIER, symbol_table->get_id(pkgname)));
- push_op(new OP(OP_SET_PACKAGE_VARIABLE, symbol_table->get_id(std::string("$") + detail)));
- return;
- }
- }
-
- int level;
- bool need_closure;
- bool is_arg;
- int no = this->find_localvar(varname, level, need_closure, is_arg);
- if (no<0) {
- fprintf(stderr, "There is no variable named %s(SETVARIABLE)\n", varname.c_str());
- this->error++;
- return;
- }
-
- SharedPtr<OP> tmp = new OP;
- if (need_closure) {
- DBG2("LOCAL\n");
- tmp->op_type = OP_SETCLOSURE;
- tmp->operand.int_value = -1;
- auto iter = closure_vars->begin();
- for (; iter!=closure_vars->end(); iter++) {
- if (*iter == varname) {
- tmp->operand.int_value = no;
- break;
- }
- }
- if (tmp->operand.int_value == -1) {
- closure_vars->push_back(varname);
- tmp->operand.int_value = closure_vars->size()-1;
- }
- } else {
- if (is_arg) {
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_SETARG;
- tmp->operand.int_value = no;
- push_op(tmp);
- } else if (level == 0) {
- DBG2("LOCAL\n");
- tmp->op_type = OP_SETLOCAL;
- tmp->operand.int_value = no;
- } else {
- DBG2("DYNAMIC\n");
- tmp->op_type = OP_SETDYNAMIC;
- tmp->operand.int_value = (((level)&0x0000ffff) << 16) | (no&0x0000ffff);
- }
- }
- push_op(tmp);
-}
-
-/**
- * assign Top of Stack to lvalue.
- *
- * @args node: lvalue node.
- * @return none.
- */
-void tora::Compiler::set_lvalue(SharedPtr<Node> node) {
- switch (node->type) {
- case NODE_GETVARIABLE: { // $a = $b;
- // fprintf(stderr, "set level: %d\n", level);
-
- std::string varname = node->upcast<StrNode>()->str_value;
- this->set_variable(varname);
- break;
- }
- case NODE_GET_ITEM: { // $a[$b] = $c
- auto container = node->upcast<BinaryNode>()->left();
- auto index = node->upcast<BinaryNode>()->right();
- this->compile(container);
- this->compile(STRING_IF_BAREWORD(index));
-
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_SET_ITEM;
- push_op(tmp);
- break;
- }
- case NODE_TUPLE: { // ($a, $b, $c[0]) = $d
- SharedPtr<ListNode>ln = node->upcast<ListNode>();
-
- // extract
- OP* op = new OP(OP_EXTRACT_TUPLE);
- op->operand.int_value = ln->size();
- push_op(op);
-
- // and set to variables
- for (size_t i=0; i < ln->size(); i++) {
- // ($a, $b) = foo();
- // ($a[0], $b) = foo();
- switch (ln->at(i)->type) {
- case NODE_GETVARIABLE: { // $a = $b;
- std::string varname = ln->at(i)->upcast<StrNode>()->str_value;
- this->set_variable(varname);
- break;
- }
- case NODE_GET_ITEM: { // $a[$b] = $c
- auto container = ln->at(i)->upcast<BinaryNode>()->left();
- auto index = ln->at(i)->upcast<BinaryNode>()->right();
- this->compile(container);
- this->compile(STRING_IF_BAREWORD(index));
- push_op(new OP(OP_SET_ITEM));
- break;
- }
- default: {
- fprintf(stderr, "\nCompilation failed. This is not a variable node:\n");
- ln->at(i)->dump(1);
- this->error++;
- break;
- }
- }
- push_op(new OP(OP_POP_TOP));
- }
- break;
- }
- case NODE_MY: {
- SharedPtr<ListNode>ln = node->upcast<ListNode>();
- for (size_t i=0; i < ln->size(); i++) {
- if (ln->at(i)->type == NODE_TUPLE) {
- SharedPtr<ListNode> ln2 = ln->at(i)->upcast<ListNode>();
- for (size_t i=0; i < ln2->size(); i++) {
- std::string &name = ln2->at(i)->upcast<StrNode>()->str_value;
- this->define_localvar(name);
- }
- } else {
- std::string &name = ln->at(i)->upcast<StrNode>()->str_value;
- this->define_localvar(name);
- }
- }
- if (ln->size() == 1) {
- this->set_lvalue(ln->at(0));
- } else {
- printf("This is not lvalue(MY):\n");
- node->dump(1);
- this->error++;
- }
- break;
- }
- case NODE_LOCAL: {
- this->fail("Straight assign for local variable is not supported yet.");
- /*
- if (node->size() == 1) {
- push_op(new OP(OP_GET_PACKAGE_VARIABLE));
- push_op(new OP(OP_LOCAL));
-
- this->set_lvalue(node->at(0));
- } else {
- printf("This is not lvalue(MY):\n");
- node->dump(1);
- this->error++;
- }
- */
- break;
- }
- default:
- printf("This is not lvalue:\n");
- node->dump(1);
- this->error++;
- break;
- }
-}
-
-class OptimizableEnterScope {
- Compiler *compiler_;
- OP *enter;
-public:
- OptimizableEnterScope(Compiler *compiler, const SharedPtr<Node> &node) {
- int decvar_in_cond = count_variable_declare(node);
- compiler_ = compiler;
- if (decvar_in_cond) {
- enter = new OP(OP_ENTER);
- compiler->push_op(enter);
- compiler->push_block(BLOCK_TYPE_BLOCK);
- } else {
- enter = NULL;
- }
- }
- ~OptimizableEnterScope() {
- if (enter) {
- compiler_->push_op(new OP(OP_LEAVE));
- enter->operand.int_value = compiler_->blocks->back()->vars.size();
- compiler_->pop_block();
- }
- }
-};
-
-bool tora::Compiler::is_builtin(const std::string &s) {
- const char *bs[] = {
- "say",
- "__PACKAGE__",
- "p",
- "require",
- "eval",
- "do",
- "print",
- "self",
- "opendir",
- "typeof",
- "rand",
- "open",
- "exit",
- "dump_stack",
- "caller",
- "callee",
- "getcwd",
- "getpid",
- "getppid",
- "abs", "atan2", "cos", "exp", "hex", "int", "log", "oct", "rand",
- "sin", "sqrt", "srand",
- NULL
- };
- for (int i=0; bs[i]; i++) {
- if (s == bs[i]) {
- return true;
- }
- }
- return false;
-}
-
-void tora::Compiler::compile(const SharedPtr<Node> &node) {
- this->current_node.reset(node.get());
-
- switch (node->type) {
- case NODE_ROOT: {
- this->push_block(BLOCK_TYPE_FILE);
- ID package_id = this->symbol_table->get_id(this->package());
- OP *pkg = new OP(OP_PACKAGE_ENTER);
- pkg->operand.int_value = package_id;
- push_op(pkg);
-
- this->push_block(BLOCK_TYPE_BLOCK);
- OP *enter = new OP(OP_ENTER);
- push_op(enter);
-
- this->compile(node->upcast<NodeNode>()->node());
-
- push_op(new OP(OP_END));
-
- enter->operand.int_value = this->blocks->back()->vars.size();
- this->pop_block();
-
- push_op(new OP(OP_PACKAGE_LEAVE));
- this->pop_block();
-
- break;
- }
- case NODE_LOCAL: {
- if (node->at(0)->type != NODE_GET_PACKAGE_VARIABLE && node->at(0)->type != NODE_GETVARIABLE) {
- this->fail("You cannot localize %s\n", node->at(0)->type_name_str());
- break;
- }
- const std::string & name = node->at(0)->upcast<StrNode>()->str_value;
-
- int level; bool need_closure; bool is_arg;
- int ret = find_localvar(name, level, need_closure, is_arg);
- if (ret >= 0) {
- this->fail("You cannot localize lexical vars: %s\n", name.c_str());
- break;
- }
-
- SharedPtr<StrValue> sv = new StrValue(node->at(0)->upcast<StrNode>()->str_value);
- SharedPtr<ValueOP> tmp = new ValueOP(OP_PUSH_STRING, sv);
- push_op(tmp);
- push_op(new OP(OP_LOCAL));
-
- if (node->at(1)) {
- // local $Foo::Bar(at0) = $val(at1);
- this->compile(node->at(1));
- this->set_lvalue(node->at(0));
- } else {
- // local $Foo::Bar(at0);
- this->compile(node->at(0));
- }
-
- break;
- }
- case NODE_RETURN: {
- SharedPtr<ListNode>ln = node->upcast<ListNode>();
-
- if (this->in_try_block) {
- ln->list->insert(ln->list->begin(), new Node(NODE_UNDEF));
- }
-
- if (ln->size() == 1) {
- this->compile(ln->at(0));
- push_op(new OP(OP_RETURN));
- } else if (ln->size() == 0) {
- push_op(new OP(OP_PUSH_UNDEF));
- push_op(new OP(OP_RETURN));
- } else {
- for (size_t i=0; i < ln->size(); i++) {
- this->compile(ln->at(i));
- }
-
- SharedPtr<OP> op = new OP(OP_MAKE_TUPLE);
- op->operand.int_value = ln->size();
- push_op(op);
-
- push_op(new OP(OP_RETURN));
- }
-
- break;
- }
- case NODE_BLOCK: {
- {
- OptimizableEnterScope es(this, node->upcast<NodeNode>()->node());
- this->compile(node->upcast<NodeNode>()->node());
- }
-
- break;
- }
- case NODE_LAMBDA: {
- /*
- struct {
- std::vector<Node*> *params;
- Node *block;
- } funcdef;
-
- putcodevalue v
- make_function
- */
-
- Compiler::TryGuard guard(this, false);
-
- auto funcdef_node = node->upcast<FuncdefNode>();
-
- // function name
-
- this->push_block(BLOCK_TYPE_FUNCDEF);
- auto params = new std::vector<std::string *>();
- if (funcdef_node->params() && funcdef_node->params()->size() > 0) {
- for (size_t i=0; i<funcdef_node->params()->size(); i++) {
- params->push_back(new std::string(funcdef_node->params()->at(i)->upcast<StrNode>()->str_value));
- this->define_localvar(std::string(funcdef_node->params()->at(i)->upcast<StrNode>()->str_value));
- }
- } else {
- params->push_back(new std::string("$_"));
- this->define_localvar(std::string("$_"));
- }
-
- Compiler funccomp(this->symbol_table, filename_);
- funccomp.init_globals();
- if (funccomp.blocks) {
- delete funccomp.blocks;
- funccomp.blocks = NULL;
- }
- funccomp.package(this->package());
- funccomp.blocks = new std::vector<SharedPtr<Block>>(*(this->blocks));
- if (funcdef_node->block()) {
- funccomp.compile(funcdef_node->block());
- }
- this->pop_block();
-
- funccomp.push_op(new OP(OP_RETURN));
- if (this->dump_ops) {
- Disasm::disasm(funccomp.ops);
- }
-
- // printf("CLOSURE VARS: %d\n", funccomp.closure_vars->size());
-
- SharedPtr<CodeValue> code = new CodeValue(
- this->symbol_table->get_id("<lambda>"), // package id
- this->symbol_table->get_id("<lambda>"), // func name id
- filename_,
- node->lineno
- );
- assert(params);
- code->code_params = params;
- code->code_opcodes = funccomp.ops;
- code->closure_var_names = new std::vector<std::string>(*funccomp.closure_vars);
-
- // if (funccomp.closure_vars->size() > 0) {
- // create closure
- // push variables to stack.
- auto iter = funccomp.closure_vars->begin();
- for (; iter!=funccomp.closure_vars->end(); iter++) {
- this->compile(new StrNode(NODE_GETVARIABLE, *iter));
- }
-
- SharedPtr<ValueOP> putval = new ValueOP(OP_PUSH_VALUE, code);
- push_op(putval);
-
- // define method.
- SharedPtr<OP> op = new OP(OP_CLOSUREDEF);
- op->operand.int_value = funccomp.closure_vars->size();
- push_op(op);
- // } else {
- /*
- SharedPtr<ValueOP> putval = new ValueOP(OP_PUSH_VALUE, code);
- push_op(putval);
-
- // create normal function
- SharedPtr<OP> define_method = new OP(OP_FUNCDEF);
- push_op(define_method);
- */
- // }
-
- push_op(new ValueOP(OP_PUSH_VALUE, code.get()));
-
- break;
- }
- case NODE_FUNCDEF: {
- /*
- struct {
- Node *name;
- std::vector<Node*> *params;
- Node *block;
- } funcdef;
-
- putcodevalue v
- make_function
- */
-
- Compiler::TryGuard guard(this, false);
-
- auto funcdef_node = node->upcast<FuncdefNode>();
-
- OP * skip_defvars = new OP(OP_JUMP);
- push_op(skip_defvars);
-
- // function name
- std::string &name = funcdef_node->name()->upcast<StrNode>()->str_value;
-
- this->push_block(BLOCK_TYPE_FUNCDEF);
- auto params = new std::vector<std::string *>();
- auto defaults = new std::vector<int>();
- for (size_t i=0; i<funcdef_node->params()->size(); i++) {
- assert(funcdef_node->params()->at(i)->list->size() == 2);
- const SharedPtr<Node>& param_name = funcdef_node->params()->at(i)->at(0);
- const SharedPtr<Node>& default_node = funcdef_node->params()->at(i)->at(1);
-
- params->push_back(new std::string(param_name->upcast<StrNode>()->str_value));
- if (default_node.get()) {
- // compile arguments to anonymous function.
- defaults->push_back(ops->size());
- this->compile(default_node);
- push_op(new OP(OP_END));
- } else {
- defaults->push_back(-1);
- }
- this->define_localvar(std::string(param_name->upcast<StrNode>()->str_value));
- }
- skip_defvars->operand.int_value = ops->size();
-
- std::string package(this->package());
- std::string funcname(name);
- bool splitted = tora::split_package_funname(name, package, funcname);
-
- Compiler funccomp(this->symbol_table, filename_);
- funccomp.init_globals();
- if (funccomp.blocks) {
- delete funccomp.blocks;
- funccomp.blocks = NULL;
- }
- funccomp.package(package);
- funccomp.blocks = new std::vector<SharedPtr<Block>>(*(this->blocks));
- funccomp.compile(funcdef_node->block());
- this->pop_block();
-
- funccomp.push_op(new OP(OP_RETURN));
- if (this->dump_ops) {
- Disasm::disasm(funccomp.ops);
- }
-
- // printf("CLOSURE VARS: %d\n", funccomp.closure_vars->size());
-
- SharedPtr<CodeValue> code = new CodeValue(
- this->symbol_table->get_id(package), // package id
- this->symbol_table->get_id(funcname), // func name id
- filename_,
- node->lineno
- );
- assert(params);
- code->package_id = splitted ? symbol_table->get_id(package) : 0;
- code->code_id = this->symbol_table->get_id(package + "::" + funcname);
- code->code_params = params;
- code->code_defaults = defaults;
- code->code_opcodes = funccomp.ops;
- code->closure_var_names = new std::vector<std::string>(*funccomp.closure_vars);
-
- SharedPtr<StrValue> funcname_value = new StrValue(funcname);
- if (funccomp.closure_vars->size() > 0) {
- // create closure
- // push variables to stack.
- auto iter = funccomp.closure_vars->begin();
- for (; iter!=funccomp.closure_vars->end(); iter++) {
- this->compile(new StrNode(NODE_GETVARIABLE, *iter));
- }
-
- SharedPtr<ValueOP> putval = new ValueOP(OP_PUSH_VALUE, code);
- push_op(putval);
-
- // define method.
- SharedPtr<OP> op = new OP(OP_CLOSUREDEF);
- op->operand.int_value = funccomp.closure_vars->size();
- push_op(op);
- } else {
- SharedPtr<ValueOP> putval = new ValueOP(OP_PUSH_VALUE, code);
- push_op(putval);
-
- // create normal function
- SharedPtr<OP> define_method = new OP(OP_FUNCDEF);
- push_op(define_method);
- }
-
- push_op(new ValueOP(OP_PUSH_VALUE, code.get()));
-
- break;
- }
- case NODE_STRING: {
- SharedPtr<StrValue> sv = new StrValue(node->upcast<StrNode>()->str_value);
- SharedPtr<ValueOP> tmp = new ValueOP(OP_PUSH_STRING, sv);
- push_op(tmp);
- break;
- }
- case NODE_BYTES: {
- SharedPtr<BytesValue> sv = new BytesValue(node->upcast<StrNode>()->str_value);
- SharedPtr<ValueOP> tmp = new ValueOP(OP_PUSH_VALUE, sv);
- push_op(tmp);
- break;
- }
- case NODE_REGEXP: {
- auto re = node->upcast<RegexpNode>();
- SharedPtr<AbstractRegexpValue> sv = new RE2RegexpValue(re->regexp_value, re->flags);
- if (!sv->ok()) {
- fprintf(stderr, "Regexp compilation failed: /%s/ : %s\n", sv->pattern().c_str(), sv->error().c_str());
- this->error++;
- break;
- }
- push_op(new ValueOP(OP_PUSH_VALUE, sv));
- break;
- }
- case NODE_RANGE: {
- this->compile(node->upcast<BinaryNode>()->right());
- this->compile(node->upcast<BinaryNode>()->left());
- push_op(new OP(OP_NEW_RANGE));
- break;
- }
- case NODE_INT: {
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_PUSH_INT;
- tmp->operand.int_value = node->upcast<IntNode>()->int_value;
- push_op(tmp);
- break;
- }
- case NODE_DOUBLE: {
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_PUSH_DOUBLE;
- tmp->operand.double_value = node->upcast<DoubleNode>()->double_value;
- push_op(tmp);
- break;
- }
- case NODE_SELF: {
- push_op(new OP(OP_PUSH_SELF));
- break;
- }
- case NODE_TRUE: {
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_PUSH_TRUE;
- push_op(tmp);
- break;
- }
- case NODE_UNDEF: {
- push_op(new OP(OP_PUSH_UNDEF));
- break;
- }
- case NODE_FALSE: {
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_PUSH_FALSE;
- push_op(tmp);
- break;
- }
- case NODE_IDENTIFIER: {
- ID id = this->symbol_table->get_id(node->upcast<StrNode>()->str_value);
- SharedPtr<OP> o = new OP(OP_PUSH_IDENTIFIER);
- o->operand.int_value = id;
- push_op(o);
- break;
- }
-
- case NODE_FUNCALL: {
- LoopContext lc(this, false);
-
- auto args = node->upcast<FuncallNode>()->args();
- int args_len = args->size();
- for (auto iter=args->rbegin(); iter!=args->rend(); iter++) {
- this->compile(*iter);
- }
-
- std::string funcname = node->upcast<FuncallNode>()->name()->upcast<StrNode>()->str_value;
-
- if (this->is_builtin(funcname)) {
- ID id = this->symbol_table->get_id(node->upcast<FuncallNode>()->name()->upcast<StrNode>()->str_value);
- SharedPtr<ValueOP> o = new ValueOP(OP_PUSH_VALUE, new SymbolValue(id));
- push_op(o);
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_BUILTIN_FUNCALL;
- tmp->operand.int_value = args_len; // the number of args
- push_op(tmp);
- } else {
- /*
- std::string funcname2 = funcname.find("::")==std::string::npos
- ? this->package() + "::" + funcname
- : funcname;
- */
- std::string funcname2(funcname);
- std::string pkgname;
- bool splitted = tora::split_package_funname(funcname, pkgname, funcname2);
- ID id = this->symbol_table->get_id(funcname2);
- SharedPtr<ValueOP> o = new ValueOP(OP_PUSH_VALUE, new SymbolValue(id));
- push_op(o);
- SharedPtr<OP> tmp = new OP(OP_FUNCALL, args_len, splitted ? symbol_table->get_id(pkgname) : 0);
- push_op(tmp);
- }
- break;
- }
-#define C_OP_BINARY(type) \
- { \
- this->compile(node->upcast<BinaryNode>()->left()); \
- this->compile(node->upcast<BinaryNode>()->right()); \
- SharedPtr<OP> tmp = new OP; \
- tmp->op_type = (type); \
- push_op(tmp); \
- break; \
- }
-
- case NODE_ADD: C_OP_BINARY(OP_ADD);
- case NODE_SUB: C_OP_BINARY(OP_SUB);
- case NODE_MUL: C_OP_BINARY(OP_MUL);
- case NODE_MOD: C_OP_BINARY(OP_MOD);
- case NODE_DIV: C_OP_BINARY(OP_DIV);
- case NODE_POW: C_OP_BINARY(OP_POW);
- case NODE_LT: C_OP_BINARY(OP_LT);
- case NODE_GT: C_OP_BINARY(OP_GT);
- case NODE_LE: C_OP_BINARY(OP_LE);
- case NODE_GE: C_OP_BINARY(OP_GE);
- case NODE_EQ: C_OP_BINARY(OP_EQ);
- case NODE_NE: C_OP_BINARY(OP_NE);
- case NODE_BITAND: C_OP_BINARY(OP_BITAND);
- case NODE_BITOR: C_OP_BINARY(OP_BITOR);
- case NODE_BITXOR: C_OP_BINARY(OP_BITXOR);
- case NODE_BITLSHIFT: C_OP_BINARY(OP_BITLSHIFT);
- case NODE_BITRSHIFT: C_OP_BINARY(OP_BITRSHIFT);
-#undef C_OP_BINARY
-
- // TODO: deprecate?
- case NODE_STMTS: {
- push_op(new OP(OP_NEXTSTATE));
- this->compile(node->upcast<BinaryNode>()->left());
- push_op(new OP(OP_NEXTSTATE));
- this->compile(node->upcast<BinaryNode>()->right());
- break;
- }
- case NODE_STMTS_LIST: {
- SharedPtr<ListNode> ln = node->upcast<ListNode>();
- for (int i=0; i<ln->size(); i++) {
- push_op(new OP(OP_NEXTSTATE));
- this->compile(ln->at(i));
- }
- break;
- }
- case NODE_IF: {
- /*
- if (cond) {
- if_body
- } else {
- else_body
- }
-
- run(cond)
- jump_if_false ELSE_LABEL
- run_if_body
- jump END_LABEL
- ELSE_LABEL:
- run_else_body
- END_LABEL:
-
- run(cond)
- jump_if_false ELSE_LABEL
- run_if_body
- jump END_LABEL
- ELSE_LABEL:
- END_LABEL:
- */
- auto if_node = node->upcast<IfNode>();
-
- OptimizableEnterScope oes(this, if_node->cond());
-
- {
-
- this->compile(if_node->cond());
-
- SharedPtr<OP> jump_else = new OP;
- jump_else->op_type = OP_JUMP_IF_FALSE;
- push_op(jump_else);
-
- if (if_node->if_body()) {
- this->compile(if_node->if_body());
- }
-
- SharedPtr<OP> jump_end = new OP;
- jump_end->op_type = OP_JUMP;
- push_op(jump_end);
-
- int else_label = ops->size();
- jump_else->operand.int_value = else_label;
- if (if_node->else_body()) {
- this->compile(if_node->else_body());
- }
-
- int end_label = ops->size();
- jump_end->operand.int_value = end_label;
-
- }
-
- break;
- }
- case NODE_WHILE: {
- /*
- LABEL1:
- cond
- jump_if_false LABEL2
- body
- goto LABEL1
- LABEL2:
- */
-
- int label1 = ops->size();
- this->compile(node->upcast<BinaryNode>()->left()); // cond
-
- LoopContext lc(this, true);
-
- SharedPtr<OP> jump_if_false = new OP;
- jump_if_false->op_type = OP_JUMP_IF_FALSE;
- push_op(jump_if_false);
-
- OP *enter = new OP(OP_ENTER_WHILE);
- push_op(enter);
- this->push_block(BLOCK_TYPE_BLOCK);
-
- this->compile(node->upcast<BinaryNode>()->right()); //body
-
- push_op(new OP(OP_LEAVE));
- enter->operand.int_value = this->blocks->back()->vars.size();
- this->pop_block();
-
- SharedPtr<OP> goto_ = new OP;
- goto_->op_type = OP_JUMP;
- goto_->operand.int_value = label1;
- push_op(goto_);
-
- int label2 = ops->size();
- jump_if_false->operand.int_value = label2;
-
- BOOST_FOREACH(auto n, last_labels) {
- *n = label2;
- }
- last_labels.clear();
-
- break;
- }
- case NODE_VOID:
- // nop
- break;
- case NODE_NEWLINE:
- // nop
- break;
- case NODE_GETVARIABLE: {
- std::string & varname = node->upcast<StrNode>()->str_value;
- int global = this->find_global_var(varname);
- auto pos = varname.rfind("::");
- if (global >= 0) {
- SharedPtr<OP> tmp = new OP();
- tmp->op_type = OP_GETGLOBAL;
- tmp->operand.int_value = global;
- push_op(tmp);
- } else if (pos != std::string::npos) {
- // package variable $Foo::Bar.
- std::string pkgname = varname.substr(1, pos-1);
- std::string detail = varname.substr(pos+2);
- push_op(new OP(OP_PUSH_IDENTIFIER, symbol_table->get_id(pkgname)));
- push_op(new OP(OP_GET_PACKAGE_VARIABLE, symbol_table->get_id(std::string("$") + detail)));
- } else {
- int level;
- bool need_closure;
- bool is_arg;
- int no = this->find_localvar(std::string(node->upcast<StrNode>()->str_value), level, need_closure, is_arg);
- // dump_localvars();
- if (no<0) {
- fprintf(stderr, "There is no variable named '%s'(NODE_GETVARIABLE)\n", node->upcast<StrNode>()->str_value.c_str());
- this->error++;
- return;
- }
-
- if (need_closure) {
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_GETCLOSURE;
- tmp->operand.int_value = -1;
- auto iter = closure_vars->begin();
- for (; iter!=closure_vars->end(); iter++) {
- if (*iter == varname) {
- tmp->operand.int_value = no;
- break;
- }
- }
- if (tmp->operand.int_value == -1) {
- closure_vars->push_back(varname);
- tmp->operand.int_value = closure_vars->size()-1;
- }
- push_op(tmp);
- } else {
- if (is_arg) {
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_GETARG;
- tmp->operand.int_value = no;
- push_op(tmp);
- } else if (level == 0) {
- DBG2("LOCAL\n");
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_GETLOCAL;
- tmp->operand.int_value = no;
- push_op(tmp);
- } else {
- SharedPtr<OP> tmp = new OP;
- DBG2("DYNAMIC\n");
- tmp->op_type = OP_GETDYNAMIC;
- tmp->operand.int_value = (((level)&0x0000ffff) << 16) | (no&0x0000ffff);
- push_op(tmp);
- }
- }
- }
- break;
- }
- // '$x /= 3;' => '$x = $x / 3'
- // TODO: optimize
-#define BINARY_ASSIGN(ccc, nnn) \
- case ccc: { \
- SharedPtr<BinaryNode> r = new BinaryNode(nnn, \
- node->upcast<BinaryNode>()->left(), \
- node->upcast<BinaryNode>()->right() \
- ); \
- SharedPtr<BinaryNode> p = new BinaryNode(NODE_SETVARIABLE, &(*(node->upcast<BinaryNode>()->left())), &(*(r->upcast<Node>()))); \
- this->compile(p); \
- break; \
- }
- BINARY_ASSIGN(NODE_ADD_ASSIGN, NODE_ADD)
- BINARY_ASSIGN(NODE_SUB_ASSIGN, NODE_SUB)
- BINARY_ASSIGN(NODE_MUL_ASSIGN, NODE_MUL)
- BINARY_ASSIGN(NODE_DIV_ASSIGN, NODE_DIV)
- BINARY_ASSIGN(NODE_AND_ASSIGN, NODE_BITAND)
- BINARY_ASSIGN(NODE_OR_ASSIGN, NODE_BITOR)
- BINARY_ASSIGN(NODE_OROR_ASSIGN, NODE_LOGICAL_OR)
- BINARY_ASSIGN(NODE_XOR_ASSIGN, NODE_BITXOR)
- BINARY_ASSIGN(NODE_MOD_ASSIGN, NODE_MOD)
-#undef BINARY_ASSIGN
- case NODE_SETVARIABLE: {
- // compile rvalue.
- this->compile(node->upcast<BinaryNode>()->right());
- // and assign it to lvalue.
- this->set_lvalue(node->upcast<BinaryNode>()->left());
- break;
- }
- case NODE_SETVARIABLE_MULTI: {
- this->compile(node->upcast<BinaryNode>()->right());
-
- SharedPtr<ListNode>ln = node->upcast<BinaryNode>()->left()->upcast<ListNode>();
-
- // extract
- OP* op = new OP(OP_EXTRACT_TUPLE);
- op->operand.int_value = ln->size();
- push_op(op);
-
- // and set to variables
- // TODO use set_lvalue method?
- for (size_t i=0; i < ln->size(); i++) {
- // ($a, $b) = foo();
- // ($a[0], $b) = foo();
- switch (ln->at(i)->type) {
- case NODE_GETVARIABLE: { // $a = $b;
- std::string varname = ln->at(i)->upcast<StrNode>()->str_value;
- this->set_variable(varname);
- break;
- }
- case NODE_GET_ITEM: { // $a[$b] = $c
- auto container = ln->at(i)->upcast<BinaryNode>()->left();
- auto index = ln->at(i)->upcast<BinaryNode>()->right();
- this->compile(container);
- this->compile(STRING_IF_BAREWORD(index));
- push_op(new OP(OP_SET_ITEM));
- break;
- }
- default: {
- fprintf(stderr, "Compilation failed\n");
- this->error++;
- break;
- }
- }
- push_op(new OP(OP_POP_TOP));
- }
-
- break;
- }
- case NODE_MAKE_ARRAY: {
- auto args = node->upcast<ListNode>();
- int args_len = args->size();
- while (args->size() > 0) {
- this->compile(args->back());
- args->pop_back();
- }
-
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_MAKE_ARRAY;
- tmp->operand.int_value = args_len; // the number of args
- push_op(tmp);
- break;
- }
- case NODE_MAKE_HASH: {
- auto args = node->upcast<ListNode>();
- int args_len = args->size();
- for (int i=0; i<args_len; i+=2) {
- // val
- this->compile(args->at(i+1));
-
- // key
- // in hash key, bareword is string literal.
- SharedPtr<Node> key = args->at(i);
- this->compile(STRING_IF_BAREWORD(key));
- }
-
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_MAKE_HASH;
- tmp->operand.int_value = args_len; // the number of args
- push_op(tmp);
- break;
- }
- case NODE_GET_ITEM: {
- this->compile(node->upcast<BinaryNode>()->left()); // container
-
- SharedPtr<Node> index = node->upcast<BinaryNode>()->right();
- this->compile(STRING_IF_BAREWORD(index));
-
- SharedPtr<OP> tmp = new OP;
- tmp->op_type = OP_GET_ITEM;
- push_op(tmp);
- break;
- }
-
- case NODE_UNARY_NEGATIVE: {
- this->compile(node->upcast<NodeNode>()->node());
-
- push_op(new OP(OP_UNARY_NEGATIVE));
-
- break;
- }
-
- case NODE_FOR: {
- /*
- struct {
- Node *initialize;
- Node *cond;
- Node *postfix;
- Node *block;
- } for_stmt;
-
- ENTER_FOR
- (initialize)
- LABEL1:
- (cond)
- jump_if_false LABEL2
- (block)
- (postfix)
- goto LABEL1
- LABEL2:
- LEAVE
- */
-
- OP *enter = new OP(OP_ENTER_FOR);
- push_op(enter);
- this->push_block(BLOCK_TYPE_BLOCK);
-
- this->compile(node->upcast<ForNode>()->initialize());
- int label1 = ops->size();
- this->compile(node->upcast<ForNode>()->cond());
-
- SharedPtr<OP> jump_label2 = new OP;
- jump_label2->op_type = OP_JUMP_IF_FALSE;
- push_op(jump_label2);
-
- {
- LoopContext lc(this, true);
- this->compile(node->upcast<ForNode>()->block());
- }
-
- this->compile(node->upcast<ForNode>()->postfix());
-
- SharedPtr<OP> jump_label1 = new OP;
- jump_label1->op_type = OP_JUMP;
- jump_label1->operand.int_value = label1;
- push_op(jump_label1);
-
- int label2 = ops->size();
- jump_label2->operand.int_value = label2;
-
- push_op(new OP(OP_LEAVE));
- enter->operand.int_value = this->blocks->back()->vars.size();
- this->pop_block();
-
- BOOST_FOREACH(auto n, last_labels) {
- *n = label2;
- }
- last_labels.clear();
-
- break;
- }
- case NODE_FOREACH: {
- /*
- struct {
- Node *vars;
- Node *source;
- Node *block;
- } for_stmt;
-
- for ($x IN $array) { ... }
-
- GET_ITER source
- LABEL1:
- FOR_ITER iter
- jump_if_stop LABEL2
- STORE $x
- (block)
- goto LABEL1
- LABEL2:
- */
-
- LoopContext lc(this, true);
- this->compile(node->upcast<ForEachNode>()->source());
-
- this->push_block(BLOCK_TYPE_BLOCK);
- OP *enter_foreach = new OP(OP_ENTER_FOREACH);
- push_op(enter_foreach);
-
- size_t label1 = ops->size();
-
- push_op(new OP(OP_FOR_ITER));
- SharedPtr<OP> jump_label2 = new OP();
- jump_label2->op_type = OP_JUMP_IF_STOP_EXCEPTION;
- push_op(jump_label2); // FIX ME?
-
- // store variables
- if (node->upcast<ForEachNode>()->vars()) {
- this->set_lvalue(node->upcast<ForEachNode>()->vars());
- } else {
- SharedPtr<ListNode> nl = new ListNode(NODE_MY);
- nl->push_back(new StrNode(NODE_GETVARIABLE, "$_"));
- this->set_lvalue(nl.get());
- }
-
- this->compile(node->upcast<ForEachNode>()->block());
-
- SharedPtr<OP> jump_label1 = new OP;
- jump_label1->op_type = OP_JUMP;
- jump_label1->operand.int_value = label1;
- push_op(jump_label1);
-
- size_t label2 = ops->size();
- jump_label2->operand.int_value = label2;
-
- enter_foreach->operand.int_value = this->blocks->back()->vars.size();
- this->pop_block();
-
- push_op(new OP(OP_LEAVE));
-
- BOOST_FOREACH(auto n, last_labels) {
- *n = label2;
- }
- last_labels.clear();
-
- break;
- }
- case NODE_METHOD_CALL: {
- /*
- node->method_call.object = $1;
- node->method_call.method = $3;
- node->method_call.args = $5;
- */
-
- LoopContext lc(this, false);
-
- auto mcn = node->upcast<MethodCallNode>();
- auto args = mcn->args();
- int args_len = args->size();
- while (args->size() > 0) {
- this->compile(args->back());
- args->pop_back();
- }
- if (mcn->method()) {
- if (mcn->method()->type == NODE_IDENTIFIER) {
- ID id = this->symbol_table->get_id(mcn->method()->upcast<StrNode>()->str_value);
- SharedPtr<ValueOP> o = new ValueOP(OP_PUSH_VALUE, new SymbolValue(id));
- push_op(o);
- } else {
- fprintf(stderr, "Compilation error. This is not a id.\n");
- error++;
- break;
- }
- } else {
- // closure call
- ID id = symbol_table->get_id("()");
- SharedPtr<ValueOP> o = new ValueOP(OP_PUSH_VALUE, new SymbolValue(id));
- push_op(o);
- }
- this->compile(mcn->object());
-
- SharedPtr<OP> op = new OP(OP_METHOD_CALL);
- op->operand.int_value = args_len;
- push_op(op);
- break;
- }
- case NODE_NOT: {
- // ! $val
- this->compile(node->upcast<NodeNode>()->node());
- push_op(new OP(OP_NOT));
- break;
- }
- case NODE_FILE_TEST: {
- // -f $file
- OP *op = new OP(OP_FILE_TEST);
- op->operand.int_value = node->upcast<BinaryNode>()->left()->upcast<IntNode>()->int_value;
- this->compile(node->upcast<BinaryNode>()->right());
- push_op(op);
- break;
- }
- case NODE_POST_DECREMENT: {
- // $i--
- this->compile(node->upcast<NodeNode>()->node());
- push_op(new OP(OP_POST_DECREMENT));
- break;
- }
- case NODE_PRE_DECREMENT: {
- // --$i
- this->compile(node->upcast<NodeNode>()->node());
- push_op(new OP(OP_PRE_DECREMENT));
- break;
- }
- case NODE_POST_INCREMENT: {
- // $i++
- this->compile(node->upcast<NodeNode>()->node());
- push_op(new OP(OP_POST_INCREMENT));
- break;
- }
- case NODE_PRE_INCREMENT: {
- // ++$i
- this->compile(node->upcast<NodeNode>()->node());
- push_op(new OP(OP_PRE_INCREMENT));
- break;
- }
- case NODE_TUPLE: {
- SharedPtr<ListNode>ln = node->upcast<ListNode>();
- for (size_t i=0; i < ln->size(); i++) {
- this->compile(ln->at(i));
- }
- OP *op = new OP(OP_MAKE_TUPLE);
- op->operand.int_value = ln->size();
- push_op(op);
- break;
- }
- case NODE_DOTDOTDOT: {
- push_op(new OP(OP_DOTDOTDOT));
- break;
- }
- case NODE_TRY: {
- LoopContext lc(this, false);
-
- Compiler::TryGuard guard(this, true);
-
- OP *try_op = new OP(OP_TRY);
- push_op(try_op);
-
- this->push_block(BLOCK_TYPE_TRY);
- OP *enter_op = new OP(OP_ENTER);
- push_op(enter_op);
-
- SharedPtr<NodeNode> n = node->upcast<NodeNode>();
- this->compile(n->node());
-
- push_op(new OP(OP_PUSH_UNDEF));
- push_op(new OP(OP_PUSH_UNDEF));
- OP *op = new OP(OP_MAKE_TUPLE);
- op->operand.int_value = 2;
- push_op(op);
- push_op(new OP(OP_RETURN));
-
- enter_op->operand.int_value = this->blocks->back()->vars.size();
-
- this->pop_block();
-
- try_op->operand.int_value = ops->size();
-
- break;
- }
- case NODE_DIE: {
- this->compile(node->upcast<NodeNode>()->node());
- push_op(new OP(OP_DIE));
- break;
- }
- case NODE_USE: {
- // use Test::More; # => 0
- // use Test::More *; # => 1
- // use Test::More qw(ok is); # => 1
- this->compile(node->upcast<BinaryNode>()->right());
- this->compile(node->upcast<BinaryNode>()->left());
- push_op(new OP(OP_USE));
- break;
- }
-
- case NODE_CLASS: {
- SharedPtr<ClassNode> n = node->upcast<ClassNode>();
-
- if (this->in_class_context) {
- // allow nested class?
- this->fail("You cannot nest classes.");
- abort();
- }
- this->in_class_context = true;
-
- this->push_block(BLOCK_TYPE_CLASS);
- std::string klass_name = n->klass()->upcast<StrNode>()->str_value;
- ID package_id = this->symbol_table->get_id(
- /*
- this->package() == "main"
- ? klass_name
- : this->package() + "::" + klass_name
- */
- klass_name
- );
- OP *pkg = new OP(OP_PACKAGE_ENTER);
- pkg->operand.int_value = package_id;
- push_op(pkg);
-
- if (n->parent()) {
- OP * op = new OP(OP_SET_PARENT);
- op->operand.int_value = symbol_table->get_id(n->parent()->upcast<StrNode>()->str_value);
- push_op(op);
- }
-
- if (n->block() != NULL) {
- this->compile(n->block());
- }
-
- push_op(new OP(OP_PACKAGE_LEAVE));
- this->pop_block();
-
- this->in_class_context = false;
-
- break;
- }
- case NODE_MY: {
- this->define_my(node);
- break;
- }
- case NODE_LAST: {
- // break from for/foreach/while
- if (!in_loop_context) {
- fail("You can't put \"last\" statement out of loop block.\n");
- } else {
- OP * op = new OP(OP_LAST);
- this->last_labels.push_back(&(op->operand.int_value));
- push_op(op);
- }
- break;
- }
- case NODE_LOGICAL_AND: {
- /**
- * (lhs)
- * JUMP_IF_FALSE label1
- * POP_TOP
- * (rhs)
- * label1:
- */
-
- const BinaryNode * n = static_cast<BinaryNode*>(node.get());
-
- this->compile(n->left());
-
- SharedPtr<OP> jump_else = new OP(OP_JUMP_IF_FALSE);
- push_op(jump_else);
-
- push_op(new OP(OP_POP_TOP));
- this->compile(n->right());
-
- jump_else->operand.int_value = ops->size();
-
- break;
- }
- case NODE_LOGICAL_OR: {
- /**
- * (lhs)
- * JUMP_IF_TRUE label1
- * POP_TOP
- * (rhs)
- * label1:
- */
-
- const BinaryNode * n = static_cast<BinaryNode*>(node.get());
-
- this->compile(n->left());
-
- SharedPtr<OP> jump_else = new OP(OP_JUMP_IF_TRUE);
- push_op(jump_else);
-
- push_op(new OP(OP_POP_TOP));
- this->compile(n->right());
-
- jump_else->operand.int_value = ops->size();
-
- break;
- }
- case NODE_DEREF: {
- this->compile(node->at(0));
- push_op(new OP(OP_DEREF));
- break;
- }
-
- default:
- this->error++;
- printf("[BUG] Unknown node: %s\n", node->type_name_str());
- abort();
- break;
- }
-}
View
162 src/compiler.h
@@ -1,162 +0,0 @@
-#ifndef TORA_COMPILER_H_
-#define TORA_COMPILER_H_
-
-#include "shared_ptr.h"
-#include "prim.h"
-#include "op.h"
-#include <stdarg.h>
-#include <vector>
-#include <string>
-
-namespace tora {
-
-class Node;
-class OPArray;
-class OP;
-class ValueOP;
-class SymbolTable;
-
-enum block_type_t {
- BLOCK_TYPE_BLOCK,
- BLOCK_TYPE_SUB,
- BLOCK_TYPE_FILE,
- BLOCK_TYPE_TRY,
- BLOCK_TYPE_FUNCDEF,
- BLOCK_TYPE_CLASS,
-};
-
-class Block : public Prim {
-public:
- block_type_t type;
- std::vector<std::string*> vars;
- Block(block_type_t t) : type(t) { }
- ~Block() {
- for (size_t i=0; i<vars.size(); i++) {
- delete vars.at(i);
- }
- }
-};
-
-class Compiler {
- std::string package_;
- std::string filename_;
-public:
- SharedPtr<OPArray> ops;
- std::vector<SharedPtr<Block>> *blocks;
- std::vector<std::string> *global_vars;
- std::vector<std::string> *closure_vars;
- SharedPtr<SymbolTable> symbol_table;
- int error;
- bool in_try_block;
- bool dump_ops;
- bool in_class_context;
-
- bool in_loop_context;
- std::vector<int*> last_labels;
-
- SharedPtr<Node> current_node;
-
- void package(const std::string & p) { package_ = p; }
- std::string & package() { return package_; }
-
- Compiler(const SharedPtr<SymbolTable> &symbol_table_, const std::string & filename);
- ~Compiler();
-
- void define_my(SharedPtr<Node> node);
- void define_global_var(const char *name) {
- auto iter = global_vars->begin();
- for (; iter!=global_vars->end(); iter++) {
- if (*iter==name) {
- printf("[BUG] duplicated global variable name: %s\n", name);
- abort();
- }
- }
- global_vars->push_back(name);
- }
- int find_global_var(std::string & name) {
- auto iter = global_vars->begin();
- for (; iter!=global_vars->end(); iter++) {
- if (*iter==name) {
- return iter-global_vars->begin();
- }
- }
- return -1;
- }
- void init_globals();
- void compile(const SharedPtr<Node> & node);
- void push_block(block_type_t t) {
- this->blocks->push_back(new Block(t));
- }
- void pop_block() {
- this->blocks->pop_back();
- }
- void set_lvalue(SharedPtr<Node> node);
- void set_variable(std::string &varname);
- int find_localvar(std::string name, int &level, bool &need_closure, bool &is_arg);
- void define_localvar(const char* name) {
- this->define_localvar(std::string(name));
- }
- void define_localvar(std::string name) {
- SharedPtr<Block> block = this->blocks->back();
- for (size_t i=0; i<block->vars.size(); i++) {
- if (*(block->vars.at(i)) == name) {
- fprintf(stderr, "Duplicated variable: %s\n", name.c_str());
- return;
- }
- }
- block->vars.push_back(new std::string(name));
- }
- void dump_localvars() {
- printf("-- dump_localvars --\n");
- printf("Levels: %zd\n", this->blocks->size());
- for (size_t level = 0; level < this->blocks->size(); ++level) {
- SharedPtr<Block> block = this->blocks->at(level);
- printf("[%zd]\n", level);
- for (size_t i=0; i<block->vars.size(); i++) {
- printf(" %s\n", block->vars.at(i)->c_str());
- }
- }
- printf("--------------------\n");
- }
- void fail(const char *format, ...) {
- fprintf(stderr, "Compilation failed:\n");
- va_list ap;
- va_start(ap, format);
- vfprintf(stderr, format, ap);
- va_end(ap);
-
- error++;
- }
-
- void push_op(OP * op);
- void push_op(const SharedPtr<OP> & op) {
- this->push_op(op.get());
- }
- void push_op(const SharedPtr<ValueOP> & op) {
- this->push_op(op.get());
- }
-
- bool is_builtin(const std::string &s);
-
- /**
- * This is RAII guard object.
- */
- class TryGuard {
- private:
- Compiler *c;
- bool orig;
- public:
- TryGuard(Compiler *c_, bool b) : c(c_) {
- orig = c_->in_try_block;
- c->in_try_block = b;
- }
- ~TryGuard() {
- c->in_try_block = orig; //restore
- }
- };
-};
-
-};
-
-
-#endif // TORA_COMPILER_H_
View
66 src/disasm.cc
@@ -1,66 +0,0 @@
-#include "disasm.h"
-#include "shared_ptr.h"
-#include "op.h"
-
-using namespace tora;
-
-void Disasm::disasm_op(OP* op) {
- printf("OP: %s", opcode2name[op->op_type]);
- switch (op->op_type) {
- case OP_SETLOCAL: {
- printf(" %d", op->operand.int_value);
- break;
- }
- case OP_GETLOCAL: {
- printf(" %d", op->operand.int_value);
- break;
- }
- case OP_GETDYNAMIC: {
- int level = (op->operand.int_value >> 16) & 0x0000FFFF;
- int no = op->operand.int_value & 0x0000ffff;
- printf(" level: %d, no: %d", level, no);
- break;
- }
- case OP_PUSH_INT: {
- printf(" %d", op->operand.int_value);
- break;
- }
- default:
- break;
- }
- printf("\n");
-}
-
-void Disasm::disasm(const SharedPtr<OPArray>& ops) {
- printf("-- OP DUMP --\n");
- for (size_t i=0; i<ops->size(); i++) {
- const OP* op = ops->at(i);
- printf("[%03zd] %s", i, opcode2name[op->op_type]);
- switch (op->op_type) {
- case OP_GETDYNAMIC: {
- int level = (op->operand.int_value >> 16) & 0x0000FFFF;
- int no = op->operand.int_value & 0x0000ffff;
- printf(" level: %d, no: %d", level, no);
- break;
- }
- case OP_SETDYNAMIC: {
- int level = (op->operand.int_value >> 16) & 0x0000FFFF;
- int no = op->operand.int_value & 0x0000ffff;
- printf(" level: %d, no: %d", level, no);
- break;
- }
- case OP_PUSH_INT:
- printf("\t%d", op->operand.int_value);
- break;
- case OP_PUSH_STRING:
- printf("\t'%s'", static_cast<const ValueOP*>(op)->value->upcast<StrValue>()->str_value.c_str());
- break;
- default:
- // nop.
- break;
- }
- printf("\n");
- }
- printf("----------------\n");
-}
-
View
18 src/disasm.h
@@ -1,18 +0,0 @@
-#ifndef TORA_DISASM_H_
-#define TORA_DISASM_H_
-
-#include "op.h"
-#include "op_array.h"
-
-namespace tora {
-
-class Disasm {
-public:
- static void disasm_op(OP* op);
-
- static void disasm(const SharedPtr<OPArray>& ops);
-};
-
-};
-
-#endif // TORA_DISASM_H_
View
51 src/frame.cc
@@ -1,51 +0,0 @@
-#include "frame.h"