Permalink
Browse files

added new $ARGV global variable

  • Loading branch information...
1 parent 9db39fe commit dc2f408959462521150c5622780fc782bc21b0fd @tokuhirom committed Feb 12, 2012
Showing with 977 additions and 46 deletions.
  1. +1 −0 .gitignore
  2. +5 −3 SConstruct
  3. +32 −16 compiler.cc
  4. +26 −0 compiler.h
  5. +28 −0 disasm.cc
  6. +14 −0 disasm.h
  7. +850 −0 lempar.c
  8. +2 −0 main.cc
  9. +1 −1 ops.gen.cc
  10. +1 −1 ops.gen.h
  11. +1 −0 ops.gen.pl
  12. +13 −24 vm.cc
  13. +3 −1 vm.h
View
@@ -13,3 +13,4 @@ gmon.out
parser.cc
parser.h
parser.out
+lemon
View
@@ -14,7 +14,7 @@ if os.uname()[0]=='Darwin':
env.Append(CXXFLAGS=['-Wno-unneeded-internal-declaration'])
else:
env = Environment(CXX='g++')
- env.Append(CCFLAGS=['-std=c++0x'])
+ env.Append(CXXFLAGS=['-std=c++0x'])
env.Append(CXXFLAGS=['-pthread', '-Wno-sign-compare'])
env.Append(LDFLAGS=['-pthread'])
env.Append(LINKFLAGS=['-lpthread'])
@@ -49,8 +49,10 @@ if 'test' in COMMAND_LINE_TARGETS:
env.Command('ops.gen.h', 'ops.gen.pl', 'perl ops.gen.pl > ops.gen.h');
env.Command(['nodes.gen.h', 'nodes.gen.cc'], 'nodes.gen.pl', 'perl nodes.gen.pl > nodes.gen.h');
env.Command(['lexer.gen.h'], 'lexer.re', 're2c lexer.re > lexer.gen.h');
-env.Command('parser.cc', 'parser.yy', 'lemon parser.yy && mv parser.c parser.cc');
+env.Command(['parser.h', 'parser.cc'], ['parser.yy', 'lempar.c'], './lemon parser.yy && mv parser.c parser.cc');
env.Program('tora', [
- 'parser.cc main.cc value.cc compiler.cc vm.cc array.cc nodes.gen.cc node.cc op.cc ops.gen.cc regexp.cc'.split(' '),
+ 'parser.cc main.cc value.cc compiler.cc vm.cc array.cc nodes.gen.cc node.cc op.cc ops.gen.cc regexp.cc disasm.cc'.split(' '),
re2files
])
+env.Program('lemon', ['tools/lemon/lemon.c']);
+
View
@@ -17,6 +17,11 @@ int tora::Compiler::find_localvar(std::string name, int &level) {
return -1;
}
+void tora::Compiler::init_globals() {
+ this->define_global_var("$ARGV");
+ this->define_global_var("$ENV");
+}
+
void tora::Compiler::compile(SharedPtr<Node> node) {
switch (node->type) {
case NODE_ROOT: {
@@ -274,24 +279,35 @@ void tora::Compiler::compile(SharedPtr<Node> node) {
// nop
break;
case NODE_GETVARIABLE: {
- int level;
- int no = this->find_localvar(std::string(node->upcast<StrNode>()->str_value), level);
- if (no<0) {
- fprintf(stderr, "There is no variable named '%s'(NODE_GETVARIABLE)\n", node->upcast<StrNode>()->str_value.c_str());
- error = true;
- }
-
- SharedPtr<OP> tmp = new OP;
- if (level == 0) {
- DBG2("LOCAL\n");
- tmp->op_type = OP_GETLOCAL;
- tmp->operand.int_value = no;
+ int global = this->find_global_var(node->upcast<StrNode>()->str_value);
+ if (global >= 0) {
+ SharedPtr<OP> tmp = new OP();
+ tmp->op_type = OP_GETGLOBAL;
+ tmp->operand.int_value = global;
+ ops->push_back(tmp);
} else {
- DBG2("DYNAMIC\n");
- tmp->op_type = OP_GETDYNAMIC;
- tmp->operand.int_value = (((level)&0x0000ffff) << 16) | (no&0x0000ffff);
+ // find local variable
+ int level;
+ int no = this->find_localvar(std::string(node->upcast<StrNode>()->str_value), level);
+ if (no<0) {
+ fprintf(stderr, "There is no variable named '%s'(NODE_GETVARIABLE)\n", node->upcast<StrNode>()->str_value.c_str());
+ error = true;
+ }
+
+ if (level == 0) {
+ DBG2("LOCAL\n");
+ SharedPtr<OP> tmp = new OP;
+ tmp->op_type = OP_GETLOCAL;
+ tmp->operand.int_value = no;
+ ops->push_back(tmp);
+ } else {
+ SharedPtr<OP> tmp = new OP;
+ DBG2("DYNAMIC\n");
+ tmp->op_type = OP_GETDYNAMIC;
+ tmp->operand.int_value = (((level)&0x0000ffff) << 16) | (no&0x0000ffff);
+ ops->push_back(tmp);
+ }
}
- ops->push_back(tmp);
break;
}
case NODE_DIV_ASSIGN: {
View
@@ -20,16 +20,39 @@ class Compiler {
public:
std::vector<SharedPtr<OP>> *ops;
std::vector<SharedPtr<Block>> *blocks;
+ std::vector<std::string> *global_vars;
bool error;
Compiler() {
error = false;
blocks = new std::vector<SharedPtr<Block>>();
+ global_vars = new std::vector<std::string>();
ops = new std::vector<SharedPtr<OP>>();
}
~Compiler() {
+ delete global_vars;
delete ops;
delete blocks;
}
+ 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(SharedPtr<Node> node);
void push_block() {
DBG("PUSH BLOCK: %d\n", this->blocks->size());
@@ -40,6 +63,9 @@ class Compiler {
this->blocks->pop_back();
}
int find_localvar(std::string name, int &level);
+ 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++) {
View
@@ -0,0 +1,28 @@
+#include "disasm.h"
+
+void tora::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");
+}
View
@@ -0,0 +1,14 @@
+#ifndef TORA_DISASM_H_
+#define TORA_DISASM_H_
+
+#include "op.h"
+
+namespace tora {
+
+class Disasm {
+ static void disasm_op(OP* op);
+};
+
+};
+
+#endif // TORA_DISASM_H_
Oops, something went wrong.

0 comments on commit dc2f408

Please sign in to comment.