Bladeren bron

some rename

Update vm.h

some change

up

Update compiler.h
blueloveTH 3 jaren geleden
bovenliggende
commit
9d341d2ffa
6 gewijzigde bestanden met toevoegingen van 71 en 70 verwijderingen
  1. 0 3
      src/builtins.h
  2. 3 2
      src/codeobject.h
  3. 49 48
      src/compiler.h
  4. 4 1
      src/opcodes.h
  5. 3 2
      src/ref.h
  6. 12 14
      src/vm.h

+ 0 - 3
src/builtins.h

@@ -420,13 +420,10 @@ class Random:
 		return self.extract_number() / 2 ** 32
 		
 	def randint(self, a, b):
-		assert type(a) is int and type(b) is int
 		assert a <= b
 		return int(self.random() * (b - a + 1)) + a
 		
 	def uniform(self, a, b):
-        assert type(a) is int or type(a) is float
-        assert type(b) is int or type(b) is float
 		if a > b:
 			a, b = b, a
 		return self.random() * (b - a) + a

+ 3 - 2
src/codeobject.h

@@ -84,7 +84,7 @@ struct CodeObject {
         return co_blocks[_currBlockIndex].type == FOR_LOOP || co_blocks[_currBlockIndex].type == WHILE_LOOP;
     }
 
-    void __enterBlock(CodeBlockType type){
+    void __enter_block(CodeBlockType type){
         const CodeBlock& currBlock = co_blocks[_currBlockIndex];
         std::vector<int> copy(currBlock.id);
         copy.push_back(-1);
@@ -99,7 +99,7 @@ struct CodeObject {
         _currBlockIndex = co_blocks.size()-1;
     }
 
-    void __exitBlock(){
+    void __exit_block(){
         co_blocks[_currBlockIndex].end = co_code.size();
         _currBlockIndex = co_blocks[_currBlockIndex].parent;
         if(_currBlockIndex < 0) UNREACHABLE();
@@ -242,6 +242,7 @@ public:
     inline void push(T&& obj){ s_data.push_back(std::forward<T>(obj)); }
 
     inline void jump_abs(int i){ next_ip = i; }
+    inline void jump_rel(int i){ next_ip = ip + i; }
 
     void jump_abs_safe(int target){
         const Bytecode& prev = code->co_code[ip];

+ 49 - 48
src/compiler.h

@@ -323,7 +323,7 @@ public:
         }
     }
 
-    bool matchNewLines(bool repl_throw=false) {
+    bool match_newlines(bool repl_throw=false) {
         bool consumed = false;
         if (peek() == TK("@eol")) {
             while (peek() == TK("@eol")) lexToken();
@@ -336,8 +336,8 @@ public:
     }
 
     bool matchEndStatement() {
-        if (match(TK(";"))) { matchNewLines(); return true; }
-        if (matchNewLines() || peek()==TK("@eof")) return true;
+        if (match(TK(";"))) { match_newlines(); return true; }
+        if (match_newlines() || peek()==TK("@eof")) return true;
         if (peek() == TK("@dedent")) return true;
         return false;
     }
@@ -497,9 +497,9 @@ public:
     }
 
     void exprGrouping() {
-        matchNewLines(mode()==SINGLE_MODE);
+        match_newlines(mode()==SINGLE_MODE);
         EXPR_TUPLE();
-        matchNewLines(mode()==SINGLE_MODE);
+        match_newlines(mode()==SINGLE_MODE);
         consume(TK(")"));
     }
 
@@ -508,13 +508,13 @@ public:
         int _body_start = co()->co_code.size();
         int ARGC = 0;
         do {
-            matchNewLines(mode()==SINGLE_MODE);
+            match_newlines(mode()==SINGLE_MODE);
             if (peek() == TK("]")) break;
             EXPR(); ARGC++;
-            matchNewLines(mode()==SINGLE_MODE);
+            match_newlines(mode()==SINGLE_MODE);
             if(ARGC == 1 && match(TK("for"))) goto __LISTCOMP;
         } while (match(TK(",")));
-        matchNewLines(mode()==SINGLE_MODE);
+        match_newlines(mode()==SINGLE_MODE);
         consume(TK("]"));
         emit(OP_BUILD_LIST, ARGC);
         return;
@@ -526,7 +526,7 @@ __LISTCOMP:
         co()->co_code[_patch].arg = _body_end;
         emit(OP_BUILD_LIST, 0);
         EXPR_FOR_VARS();consume(TK("in"));EXPR_TUPLE();
-        matchNewLines(mode()==SINGLE_MODE);
+        match_newlines(mode()==SINGLE_MODE);
         
         int _skipPatch = emit(OP_JUMP_ABSOLUTE);
         int _cond_start = co()->co_code.size();
@@ -538,7 +538,7 @@ __LISTCOMP:
         patch_jump(_skipPatch);
 
         emit(OP_GET_ITER);
-        co()->__enterBlock(FOR_LOOP);
+        co()->__enter_block(FOR_LOOP);
         emit(OP_FOR_ITER);
 
         if(_cond_end_return != -1) {      // there is an if condition
@@ -556,8 +556,8 @@ __LISTCOMP:
         }
 
         emit(OP_LOOP_CONTINUE, -1, true);
-        co()->__exitBlock();
-        matchNewLines(mode()==SINGLE_MODE);
+        co()->__exit_block();
+        match_newlines(mode()==SINGLE_MODE);
         consume(TK("]"));
     }
 
@@ -565,7 +565,7 @@ __LISTCOMP:
         bool parsing_dict = false;
         int size = 0;
         do {
-            matchNewLines(mode()==SINGLE_MODE);
+            match_newlines(mode()==SINGLE_MODE);
             if (peek() == TK("}")) break;
             EXPR();
             if(peek() == TK(":")) parsing_dict = true;
@@ -574,7 +574,7 @@ __LISTCOMP:
                 EXPR();
             }
             size++;
-            matchNewLines(mode()==SINGLE_MODE);
+            match_newlines(mode()==SINGLE_MODE);
         } while (match(TK(",")));
         consume(TK("}"));
 
@@ -586,7 +586,7 @@ __LISTCOMP:
         int ARGC = 0;
         int KWARGC = 0;
         do {
-            matchNewLines(mode()==SINGLE_MODE);
+            match_newlines(mode()==SINGLE_MODE);
             if (peek() == TK(")")) break;
             if(peek() == TK("@id") && peek_next() == TK("=")) {
                 consume(TK("@id"));
@@ -600,7 +600,7 @@ __LISTCOMP:
                 EXPR();
                 ARGC++;
             }
-            matchNewLines(mode()==SINGLE_MODE);
+            match_newlines(mode()==SINGLE_MODE);
         } while (match(TK(",")));
         consume(TK(")"));
         emit(OP_CALL, (KWARGC << 16) | ARGC);
@@ -648,7 +648,6 @@ __LISTCOMP:
                 consume(TK("]"));
             }
         }
-
         emit(OP_BUILD_INDEX_REF);
     }
 
@@ -684,14 +683,14 @@ __LISTCOMP:
     
     void __compileBlockBody(CompilerAction action) {
         consume(TK(":"));
-        if(!matchNewLines(mode()==SINGLE_MODE)){
+        if(!match_newlines(mode()==SINGLE_MODE)){
             syntaxError("expected a new line after ':'");
         }
         consume(TK("@indent"));
         while (peek() != TK("@dedent")) {
-            matchNewLines();
+            match_newlines();
             (this->*action)();
-            matchNewLines();
+            match_newlines();
         }
         consume(TK("@dedent"));
     }
@@ -699,7 +698,7 @@ __LISTCOMP:
     Token compileImportPath() {
         consume(TK("@id"));
         Token tkmodule = parser->prev;
-        int index = co()->add_name(tkmodule.str(), NAME_GLOBAL);
+        int index = co()->add_name(tkmodule.str(), NAME_SPECIAL);
         emit(OP_IMPORT_NAME, index);
         return tkmodule;
     }
@@ -726,7 +725,7 @@ __LISTCOMP:
             emit(OP_DUP_TOP);
             consume(TK("@id"));
             Token tkname = parser->prev;
-            int index = co()->add_name(tkname.str(), NAME_GLOBAL);
+            int index = co()->add_name(tkname.str(), NAME_ATTR);
             emit(OP_BUILD_ATTR_REF, index);
             if (match(TK("as"))) {
                 consume(TK("@id"));
@@ -754,7 +753,7 @@ __LISTCOMP:
     }
 
     void compileIfStatement() {
-        matchNewLines();
+        match_newlines();
         EXPR_TUPLE();
 
         int ifpatch = emit(OP_POP_JUMP_IF_FALSE);
@@ -776,13 +775,13 @@ __LISTCOMP:
     }
 
     void compileWhileLoop() {
-        co()->__enterBlock(WHILE_LOOP);
+        co()->__enter_block(WHILE_LOOP);
         EXPR_TUPLE();
         int patch = emit(OP_POP_JUMP_IF_FALSE);
         compileBlockBody();
         emit(OP_LOOP_CONTINUE, -1, true);
         patch_jump(patch);
-        co()->__exitBlock();
+        co()->__exit_block();
     }
 
     void EXPR_FOR_VARS(){
@@ -797,26 +796,31 @@ __LISTCOMP:
     void compileForLoop() {
         EXPR_FOR_VARS();consume(TK("in")); EXPR_TUPLE();
         emit(OP_GET_ITER);
-        co()->__enterBlock(FOR_LOOP);
+        co()->__enter_block(FOR_LOOP);
         emit(OP_FOR_ITER);
         compileBlockBody();
         emit(OP_LOOP_CONTINUE, -1, true);
-        co()->__exitBlock();
+        co()->__exit_block();
     }
 
     void compileTryExcept() {
-        co()->__enterBlock(TRY_EXCEPT);
+        co()->__enter_block(TRY_EXCEPT);
         compileBlockBody();
         int patch = emit(OP_JUMP_ABSOLUTE);
-        co()->__exitBlock();
+        co()->__exit_block();
         consume(TK("except"));
-        if(match(TK("@id"))){       // exception name
-            compileBlockBody();
-        }
-        if(match(TK("finally"))){
-            consume(TK(":"));
-            syntaxError("finally is not supported yet");
+        if(match(TK("@id"))){
+            int name_idx = co()->add_name(parser->prev.str(), NAME_SPECIAL);
+            emit(OP_EXCEPTION_MATCH, name_idx);
+        }else{
+            emit(OP_LOAD_TRUE);
         }
+        int patch_2 = emit(OP_POP_JUMP_IF_FALSE);
+        emit(OP_POP_TOP);       // pop the exception on match
+        compileBlockBody();
+        emit(OP_JUMP_RELATIVE, 1);
+        patch_jump(patch_2);
+        emit(OP_RE_RAISE);      // no match, re-raise
         patch_jump(patch);
     }
 
@@ -871,23 +875,21 @@ __LISTCOMP:
             consume(TK(".")); consume(TK("@id"));
             co()->add_label(parser->prev.str());
             consumeEndStatement();
-        } else if(match(TK("goto"))){
-            // https://entrian.com/goto/
+        } else if(match(TK("goto"))){ // https://entrian.com/goto/
             if(mode() != EXEC_MODE) syntaxError("'goto' is only available in EXEC_MODE");
             consume(TK(".")); consume(TK("@id"));
-            emit(OP_LOAD_CONST, co()->add_const(vm->PyStr(parser->prev.str())));
-            emit(OP_GOTO);
+            emit(OP_GOTO, co()->add_name(parser->prev.str(), NAME_SPECIAL));
             consumeEndStatement();
         } else if(match(TK("raise"))){
-            consume(TK("@id"));         // dummy exception type
-            emit(OP_LOAD_CONST, co()->add_const(vm->PyStr(parser->prev.str())));
+            consume(TK("@id"));
+            int dummy_t = co()->add_name(parser->prev.str(), NAME_SPECIAL);
             if(match(TK("("))){
                 EXPR();
                 consume(TK(")"));
             }else{
-                emit(OP_LOAD_NONE); // ...?
+                emit(OP_LOAD_NONE);
             }
-            emit(OP_RAISE_ERROR);
+            emit(OP_RAISE, dummy_t);
             consumeEndStatement();
         } else if(match(TK("del"))){
             EXPR();
@@ -917,8 +919,7 @@ __LISTCOMP:
         consume(TK("@id"));
         int clsNameIdx = co()->add_name(parser->prev.str(), NAME_GLOBAL);
         int superClsNameIdx = -1;
-        if(match(TK("("))){
-            consume(TK("@id"));
+        if(match(TK("(")) && match(TK("@id"))){
             superClsNameIdx = co()->add_name(parser->prev.str(), NAME_GLOBAL);
             consume(TK(")"));
         }
@@ -935,7 +936,7 @@ __LISTCOMP:
         int state = 0;      // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs
         do {
             if(state == 3) syntaxError("**kwargs should be the last argument");
-            matchNewLines();
+            match_newlines();
             if(match(TK("*"))){
                 if(state < 1) state = 1;
                 else syntaxError("*args should be placed before **kwargs");
@@ -1038,7 +1039,7 @@ __LISTCOMP:
         // Lex initial tokens. current <-- next.
         lexToken();
         lexToken();
-        matchNewLines();
+        match_newlines();
 
         if(mode()==EVAL_MODE) {
             EXPR_TUPLE();
@@ -1057,7 +1058,7 @@ __LISTCOMP:
 
         while (!match(TK("@eof"))) {
             compileTopLevelStatement();
-            matchNewLines();
+            match_newlines();
         }
         code->optimize();
         return code;

+ 4 - 1
src/opcodes.h

@@ -42,6 +42,7 @@ OPCODE(JUMP_IF_TRUE_OR_POP)
 OPCODE(JUMP_IF_FALSE_OR_POP)
 
 OPCODE(GOTO)
+OPCODE(JUMP_RELATIVE)
 
 OPCODE(LOAD_CONST)
 OPCODE(LOAD_NONE)
@@ -54,7 +55,9 @@ OPCODE(LOAD_NAME)
 OPCODE(LOAD_NAME_REF)
 
 OPCODE(ASSERT)
-OPCODE(RAISE_ERROR)
+OPCODE(EXCEPTION_MATCH)
+OPCODE(RAISE)
+OPCODE(RE_RAISE)
 
 OPCODE(BUILD_INDEX_REF)
 OPCODE(BUILD_ATTR_REF)

+ 3 - 2
src/ref.h

@@ -13,8 +13,9 @@ struct BaseRef {
 
 enum NameScope {
     NAME_LOCAL = 0,
-    NAME_GLOBAL = 1,
-    NAME_ATTR = 2,
+    NAME_GLOBAL,
+    NAME_ATTR,
+    NAME_SPECIAL,
 };
 
 struct NameRef : BaseRef {

+ 12 - 14
src/vm.h

@@ -187,18 +187,18 @@ protected:
                     PyVar expr = frame->pop_value(this);
                     if(asBool(expr) != True) _error("AssertionError", "");
                 } break;
-            case OP_RAISE_ERROR:
+            case OP_EXCEPTION_MATCH: break;
+            case OP_RAISE:
                 {
-                    _Str msg = PyStr_AS_C(asRepr(frame->pop_value(this)));
-                    _Str type = PyStr_AS_C(frame->pop_value(this));
+                    _Str msg = PyStr_AS_C(asStr(frame->pop_value(this)));
+                    _Str type = frame->code->co_names[byte.arg].first;
                     _error(type, msg);
                 } break;
+            case OP_RE_RAISE: break;
             case OP_BUILD_LIST:
-                {
-                    frame->push(PyList(
-                        frame->pop_n_values_reversed(this, byte.arg).toList()
-                    ));
-                } break;
+                frame->push(PyList(
+                    frame->pop_n_values_reversed(this, byte.arg).toList()));
+                break;
             case OP_BUILD_MAP:
                 {
                     pkpy::ArgList items = frame->pop_n_values_reversed(this, byte.arg*2);
@@ -230,14 +230,12 @@ protected:
                     frame->push(std::move(ret));
                 } break;
             case OP_JUMP_ABSOLUTE: frame->jump_abs(byte.arg); break;
+            case OP_JUMP_RELATIVE: frame->jump_rel(byte.arg); break;
             case OP_SAFE_JUMP_ABSOLUTE: frame->jump_abs_safe(byte.arg); break;
             case OP_GOTO: {
-                PyVar obj = frame->pop_value(this);
-                const _Str& label = PyStr_AS_C(obj);
+                const _Str& label = frame->code->co_names[byte.arg].first;
                 int* target = frame->code->co_labels.try_get(label);
-                if(target == nullptr){
-                    _error("KeyError", "label '" + label + "' not found");
-                }
+                if(target == nullptr) _error("KeyError", "label '" + label + "' not found");
                 frame->jump_abs_safe(*target);
             } break;
             case OP_GET_ITER:
@@ -326,7 +324,7 @@ protected:
         }
 
         if(frame->code->src->mode == EVAL_MODE || frame->code->src->mode == JSON_MODE){
-            if(frame->stack_size() != 1) throw std::runtime_error("stack size is not 1 in EVAL_MODE/JSON_MODE");
+            if(frame->stack_size() != 1) throw std::runtime_error("stack size is not 1 in EVAL/JSON_MODE");
             return frame->pop_value(this);
         }