Explorar el Código

fix error pos

blueloveTH hace 3 años
padre
commit
94bda0c947
Se han modificado 7 ficheros con 114 adiciones y 26 borrados
  1. 1 1
      src/codeobject.h
  2. 6 4
      src/compiler.h
  3. 4 1
      src/main.cpp
  4. 9 1
      src/parser.h
  5. 0 13
      src/pocketpy.h
  6. 94 0
      tests/basic.py
  7. 0 6
      tests/class.pk

+ 1 - 1
src/codeobject.h

@@ -118,7 +118,7 @@ public:
 
     _Str errorSnapshot(){
         int line = -1;
-        if(!isEnd()) line = code->co_code[ip].line;
+        if(!isEnd()) line = code->co_code[ip-1].line;
         return code->src->snapshot(line);
     }
 

+ 6 - 4
src/compiler.h

@@ -120,9 +120,9 @@ public:
     _Str eatStringUntil(char quote) {
         std::vector<char> buff;
         while (true) {
-            char c = parser->eatChar();
+            char c = parser->eatCharIncludeNewLine();
             if (c == quote) break;
-            if (c == '\0') syntaxError("EOL while scanning string literal");
+            if (c == '\0' || c == '\n') syntaxError("EOL while scanning string literal");
             if (c == '\\') {
                 switch (parser->eatCharIncludeNewLine()) {
                     case '"':  buff.push_back('"');  break;
@@ -177,7 +177,8 @@ public:
     void lexToken() {
         parser->previous = parser->current;
         parser->current = parser->nextToken();
-        //printf("<%s> ", TK_STR(peek()));
+
+        //_Str _info = parser->current.info(); printf("%s\n", (const char*)_info);
 
         while (parser->peekChar() != '\0') {
             parser->token_start = parser->current_char;
@@ -871,7 +872,8 @@ __LITERAL_EXIT:
 
     /***** Error Reporter *****/
     _Str getLineSnapshot(){
-        int lineno = parser->previous.line;
+        int lineno = parser->current_line;
+        if(parser->peekChar() == '\n') lineno--;
         return parser->src->snapshot(lineno);
     }
 

+ 4 - 1
src/main.cpp

@@ -33,13 +33,16 @@ VM* newVM(){
         std::cout << str;
         std::cout.flush();
     });
-    registerModule(vm, "math", "pi = 3.141593");
     return vm;
 }
 
 void REPL(){
     std::cout << "pocketpy 0.1.0" << std::endl;
     std::cout << "https://github.com/blueloveTH/pocketpy" << std::endl;
+#ifdef PK_DEBUG
+    std::cout << "[ DEBUG MODE ENABLED ]" << std::endl;
+#endif
+
 
     int need_more_lines = 0;
 

+ 9 - 1
src/parser.h

@@ -61,6 +61,14 @@ struct Token{
   const _Str str() const {
     return _Str(start, length);
   }
+
+  const _Str info() const {
+    _StrStream ss;
+    _Str raw = str();
+    if (raw == _Str("\n")) raw = "\\n";
+    ss << line << ": " << TK_STR(type) << " '" << raw << "'";
+    return ss.str();
+  }
 };
 
 enum Precedence {
@@ -146,7 +154,7 @@ struct Parser {
 
     char eatChar() {
         char c = peekChar();
-        if(c == '\n') throw std::runtime_error("eatChar() cannot consume a newline");
+        if(c == '\n') throw UnexpectedError("eatChar() cannot consume a newline");
         current_char++;
         return c;
     }

+ 0 - 13
src/pocketpy.h

@@ -404,18 +404,6 @@ void __runCodeBuiltins(VM* vm, const char* src){
     vm->exec(code, {}, vm->builtins);
 }
 
-#include <cstdlib>
-void __addModuleRandom(VM* vm){
-    srand(time(NULL));
-    PyVar random = vm->newModule("random");
-    vm->bindFunc(random, "randint", [](VM* vm, PyVarList args) {
-        int _min = vm->PyInt_AS_C(args[0]);
-        int _max = vm->PyInt_AS_C(args[1]);
-        return vm->PyInt(rand() % (_max - _min + 1) + _min);
-    });
-    vm->_modules["random"] = random;
-}
-
 #include "builtins.h"
 
 #ifdef _WIN32
@@ -432,7 +420,6 @@ extern "C" {
         VM* vm = new VM();
         __initializeBuiltinFunctions(vm);
         __runCodeBuiltins(vm, __BUILTINS_CODE);
-        __addModuleRandom(vm);
         vm->_stdout = _stdout;
         return vm;
     }

+ 94 - 0
tests/basic.py

@@ -0,0 +1,94 @@
+# generate assert test for int
+
+# test == != >= <= < > 
+# generate 2 cases for each operator
+assert -1 == -1
+assert -1 != 1
+assert -1 >= -1
+assert -1 <= -1
+assert -1 < 1
+assert -1 > -2
+
+# test + - * % ** //
+assert -1 + 1 == 0
+assert -1 - 1 == -2
+assert 4 * -1 == -4
+assert 5 % 2 == 1
+assert 2 ** 3 == 8
+assert 4 // 2 == 2
+assert 5 // 2 == 2
+
+# test += -= *= //=
+x = 3
+x += 1
+assert x == 4
+x -= 1
+assert x == 3
+x *= 2
+assert x == 6
+x //= 2
+assert x == 3
+
+# generate assert test for float
+
+def eq(a, b):
+    dt = a - b
+    return dt > -0.001 and dt < 0.001
+
+# test + - * / **
+assert eq(1.5 + 3, 4.5)
+assert eq(1.5 + 3.9, 5.4)
+assert eq(5.3 - 2.5, 2.8)
+assert eq(0.2**2, 0.04)
+assert eq(4**(-1.0), 0.25)
+assert eq(2/1, 2)
+assert eq(3/2.0, 1.5)
+assert eq(1/9, 0.11111)
+
+# test += -= *= /=
+x = 3.0
+x += 1
+assert eq(x, 4.0)
+x -= 1
+assert eq(x, 3.0)
+x *= 2
+assert eq(x, 6.0)
+x /= 1.8
+assert eq(x, 3.3333)
+
+# generate assert test for bool
+
+assert True == True
+assert True != False
+assert False == False
+assert False != True
+
+# test and/or/not
+assert True and True
+assert not (True and False)
+assert True or True
+assert True or False
+assert not False
+assert not (not True)
+
+# generate assert test for str
+
+assert 'testing' == 'test' + 'ing'
+assert 'testing' != 'test' + 'ing2'
+assert 'testing' < 'test' + 'ing2'
+assert 'testing5' > 'test' + 'ing1'
+
+# test + *=
+assert 'abc' + 'def' == 'abcdef'
+assert 'abc' * 3 == 'abcabcabc'
+
+# generate assert test for list
+
+assert [1, 2, 3] == [1, 2, 3]
+assert [1, 2, 3] != [1, 2, 4]
+
+# test + *=
+assert [1, 2, 3] + [4, 5, 6] == [1, 2, 3, 4, 5, 6]          
+assert [1, 2, 3] * 3 == [1, 2, 3, 1, 2, 3, 1, 2, 3]
+
+print("ALL TESTS PASSED")

+ 0 - 6
tests/class.pk

@@ -1,6 +0,0 @@
-class Complex:
-    def __init__(self, realpart, imagpart):
-        self.r = realpart
-        self.i = imagpart
-x = Complex(3.0, -4.5)
-assert x.r == 3.0