Skip to content

Commit

Permalink
fix(parser): add currect traceback to CommandError
Browse files Browse the repository at this point in the history
Now you can see traceback to kola file in KoiLangCommandError.
Fix command field inherit.
Change KoiLang.parse_file and KoiLang.parse_string.
  • Loading branch information
Ovizro committed Sep 14, 2022
1 parent c8c8150 commit 2752f4c
Show file tree
Hide file tree
Showing 6 changed files with 795 additions and 889 deletions.
109 changes: 78 additions & 31 deletions kola/_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
extern "C" {
#endif

enum TokenSyn {
static enum TokenSyn {
CMD=1, CMD_N, TEXT, LITERAL, STRING, NUM, NUM_H, NUM_B, NUM_F, CLN, CMA, SLP, SRP
} TokenSyn;

Expand Down Expand Up @@ -57,6 +57,10 @@ static const char* get_format(int code) {
{
case 1:
ERR_MSG(unknown symbol '%s');
case 2:
ERR_MSG(command '%s' not found);
case 3:
ERR_MSG(an error occured during handling command '%s');
case 10:
ERR_MSG(end of line in incurrect place);
case 28:
Expand All @@ -80,42 +84,85 @@ static const char* get_format(int code) {
#include "frameobject.h"
// For Cython limiting, error setting function has to define here
static void __inline kola_set_error(PyObject* exc_type, int errorno,
const char* filename, int lineno, char* text)
const char* filename, int lineno, const char* text)
{
PyErr_Format(exc_type, get_format(errorno), errorno, text);

// add traceback in .kola file
#if PY_VERSION_HEX >= 0x03080000
_PyTraceback_Add("<kola>", filename, lineno);
#else
PyCodeObject* code = NULL;
PyFrameObject* frame = NULL;
PyObject* globals = NULL;
PyObject *exc, *val, *tb;
#if PY_VERSION_HEX >= 0x03080000
_PyTraceback_Add("<kola>", filename, lineno);
#else
PyCodeObject* code = NULL;
PyFrameObject* frame = NULL;
PyObject* globals = NULL;
PyObject *exc, *val, *tb;

PyErr_Fetch(&exc, &val, &tb);

globals = PyDict_New();
if (!globals) goto end;
code = PyCode_NewEmpty(filename, "<kola>", lineno);
if (!code) goto end;
frame = PyFrame_New(
PyThreadState_Get(),
code,
globals,
NULL
);
if (!frame) goto end;

frame->f_lineno = lineno;
PyErr_Restore(exc, val, tb);
PyTraceBack_Here(frame);

end:
Py_XDECREF(code);
Py_XDECREF(frame);
Py_XDECREF(globals);
#endif
}

static void __inline kola_set_errcause(PyObject* exc_type, int errorno,
const char* filename, int lineno, const char* text, PyObject* cause)
{
PyErr_Format(exc_type, get_format(errorno), errorno, text);

PyObject *exc, *val, *tb;
PyErr_Fetch(&exc, &val, &tb);

globals = PyDict_New();
if (!globals) goto end;
code = PyCode_NewEmpty(filename, "<kola>", lineno);
if (!code) goto end;
frame = PyFrame_New(
PyThreadState_Get(),
code,
globals,
NULL
);
if (!frame) goto end;

frame->f_lineno = lineno;
PyErr_Restore(exc, val, tb);
PyTraceBack_Here(frame);

end:
Py_XDECREF(code);
Py_XDECREF(frame);
Py_XDECREF(globals);
#endif
if (cause == Py_None) {
PyException_SetContext(val, NULL);
} else {
Py_INCREF(cause);
PyException_SetCause(val, cause);
}
#if PY_VERSION_HEX >= 0x03080000
PyErr_Restore(exc, val, tb);
_PyTraceback_Add("<kola>", filename, lineno);
#else
PyCodeObject* code = NULL;
PyFrameObject* frame = NULL;
PyObject* globals = NULL;
globals = PyDict_New();
if (!globals) goto end;
code = PyCode_NewEmpty(filename, "<kola>", lineno);
if (!code) goto end;
frame = PyFrame_New(
PyThreadState_Get(),
code,
globals,
NULL
);
if (!frame) goto end;

frame->f_lineno = lineno;
PyErr_Restore(exc, val, tb);
PyTraceBack_Here(frame);

end:
Py_XDECREF(code);
Py_XDECREF(frame);
Py_XDECREF(globals);
#endif
}
#endif

Expand Down
3 changes: 2 additions & 1 deletion kola/_helper.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ cdef extern from "_helper.h":
SLP
SRP
const uint8_t yy_goto[7][8]
void kola_set_error(object exc_type, int errorno, const char* filename, int lineno, char* text) except *
void kola_set_error(object exc_type, int errorno, const char* filename, int lineno, const char* text) except *
void kola_set_errcause(object exc_type, int errorno, const char* filename, int lineno, const char* text, object cause) except *
21 changes: 11 additions & 10 deletions kola/klvm.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
from argparse import ArgumentParser
import sys
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
from typing import Any, Callable, Dict, Set, Tuple, Union
from types import MethodType
from .lexer import BaseLexer, StringLexer, FileLexer
from .parser import Parser
Expand All @@ -24,10 +22,13 @@ class KoiLangMeta(type):
"""
Metaclass for KoiLang class
"""
__command_field__: List[KoiLangCommand]
__command_field__: Set[KoiLangCommand]

def __new__(cls, name: str, base: Tuple[type, ...], attr: Dict[str, Any]):
__command_field__ = [i for i in attr.values() if isinstance(i, KoiLangCommand)]
__command_field__ = {i for i in attr.values() if isinstance(i, KoiLangCommand)}
for i in base:
if isinstance(i, KoiLangMeta):
__command_field__.update(i.__command_field__)
attr["__command_field__"] = __command_field__

return super().__new__(cls, name, base, attr)
Expand All @@ -54,20 +55,20 @@ def parse(self, lexer: Union[BaseLexer, str]) -> None:
Parser(lexer, self.command_set).exec_()

def parse_file(self, path: str) -> None:
Parser(FileLexer(path), self.command_set).exec_()
self.parse(FileLexer(path))

def parse_command(self, cmd: str) -> None:
Parser(StringLexer(cmd, stat=1), self.command_set).exec_()
self.parse(StringLexer(cmd, stat=1))

def parse_args(self, args: str) -> Tuple[tuple, dict]:
return Parser(StringLexer(args, stat=2), self.command_set).parse_args()


def kola_command(func: Callable) -> KoiLangCommand:
def kola_command(func: Callable[..., Any]) -> KoiLangCommand:
return KoiLangCommand(func.__name__, func)

def kola_text(func: Callable) -> KoiLangCommand:
def kola_text(func: Callable[[Any, str], Any]) -> KoiLangCommand:
return KoiLangCommand("@text", func)

def kola_number(func: Callable) -> KoiLangCommand:
def kola_number(func: Callable[..., Any]) -> KoiLangCommand:
return KoiLangCommand("@number", func)
Loading

0 comments on commit 2752f4c

Please sign in to comment.