Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ dist/
examples/*.bin
examples/*.tzx
scratch/
.coverage/
.coverage
htmlcov/
build/
45 changes: 22 additions & 23 deletions src/api/errmsg.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@
__all__ = ['error', 'warning']


def msg_output(msg):
def msg_output(msg: str) -> None:
if msg in global_.error_msg_cache:
return

OPTIONS.stderr.write("%s\n" % msg)
global_.error_msg_cache.add(msg)


def info(msg):
def info(msg: str) -> None:
if OPTIONS.Debug < 1:
return
OPTIONS.stderr.write("info: %s\n" % msg)


def error(lineno, msg, fname: Optional[str] = None):
def error(lineno: int, msg: str, fname: Optional[str] = None) -> None:
""" Generic syntax error routine
"""
if fname is None:
Expand All @@ -51,7 +51,7 @@ def error(lineno, msg, fname: Optional[str] = None):
global_.has_errors += 1


def warning(lineno, msg, fname: Optional[str] = None):
def warning(lineno: int, msg: str, fname: Optional[str] = None) -> None:
""" Generic warning error routine
"""
if fname is None:
Expand All @@ -62,7 +62,7 @@ def warning(lineno, msg, fname: Optional[str] = None):
global_.has_warnings += 1


def warning_implicit_type(lineno, id_, type_=None):
def warning_implicit_type(lineno: int, id_: str, type_: str = None):
""" Warning: Using default implicit type 'x'
"""
if OPTIONS.strict:
Expand All @@ -75,19 +75,19 @@ def warning_implicit_type(lineno, id_, type_=None):
warning(lineno, "Using default implicit type '%s' for '%s'" % (type_, id_))


def warning_condition_is_always(lineno, cond=False):
def warning_condition_is_always(lineno: int, cond: bool = False):
""" Warning: Condition is always false/true
"""
warning(lineno, "Condition is always %s" % cond)


def warning_conversion_lose_digits(lineno):
def warning_conversion_lose_digits(lineno: int):
""" Warning: Conversion may lose significant digits
"""
warning(lineno, 'Conversion may lose significant digits')


def warning_empty_loop(lineno):
def warning_empty_loop(lineno: int):
""" Warning: Empty loop
"""
warning(lineno, 'Empty loop')
Expand All @@ -99,7 +99,7 @@ def warning_empty_if(lineno):
warning(lineno, 'Useless empty IF ignored')


# Emmits an optimization warning
# Emits an optimization warning
def warning_not_used(lineno, id_, kind='Variable'):
if OPTIONS.optimization > 0:
warning(lineno, "%s '%s' is never used" % (kind, id_))
Expand All @@ -109,71 +109,70 @@ def warning_not_used(lineno, id_, kind='Variable'):
# Syntax error: Expected string instead of
# numeric expression.
# ----------------------------------------
def syntax_error_expected_string(lineno, _type):
def syntax_error_expected_string(lineno: str, _type: str):
error(lineno, "Expected a 'string' type expression, got '%s' instead" % _type)


# ----------------------------------------
# Syntax error: FOR variable should be X
# instead of Y
# ----------------------------------------
def syntax_error_wrong_for_var(lineno, x, y):
error(lineno, "FOR variable should be '%s' instead of '%s'" %
(x, y))
def syntax_error_wrong_for_var(lineno: str, x: str, y: str):
error(lineno, "FOR variable should be '%s' instead of '%s'" % (x, y))


# ----------------------------------------
# Syntax error: Initializer expression is
# not constant
# ----------------------------------------
def syntax_error_not_constant(lineno):
def syntax_error_not_constant(lineno: int):
error(lineno, "Initializer expression is not constant.")


# ----------------------------------------
# Syntax error: Id is neither an array nor
# a function
# ----------------------------------------
def syntax_error_not_array_nor_func(lineno, varname):
def syntax_error_not_array_nor_func(lineno: int, varname: str):
error(lineno, "'%s' is neither an array nor a function." % varname)


# ----------------------------------------
# Syntax error: Id is neither an array nor
# a function
# ----------------------------------------
def syntax_error_not_an_array(lineno, varname):
def syntax_error_not_an_array(lineno: int, varname: str):
error(lineno, "'%s' is not an array (or has not been declared yet)" % varname)


# ----------------------------------------
# Syntax error: function redefinition type
# mismatch
# ----------------------------------------
def syntax_error_func_type_mismatch(lineno, entry):
def syntax_error_func_type_mismatch(lineno: int, entry):
error(lineno, "Function '%s' (previously declared at %i) type mismatch" % (entry.name, entry.lineno))


# ----------------------------------------
# Syntax error: function redefinition parm.
# mismatch
# ----------------------------------------
def syntax_error_parameter_mismatch(lineno, entry):
def syntax_error_parameter_mismatch(lineno: int, entry):
error(lineno, "Function '%s' (previously declared at %i) parameter mismatch" % (entry.name, entry.lineno))


# ----------------------------------------
# Syntax error: can't convert value to the
# given type.
# ----------------------------------------
def syntax_error_cant_convert_to_type(lineno, expr_str, type_):
def syntax_error_cant_convert_to_type(lineno: int, expr_str: str, type_: str):
error(lineno, "Cant convert '%s' to type %s" % (expr_str, type_))


# ----------------------------------------
# Syntax error: is a SUB not a FUNCTION
# ----------------------------------------
def syntax_error_is_a_sub_not_a_func(lineno, name):
def syntax_error_is_a_sub_not_a_func(lineno: int, name: str):
error(lineno, "'%s' is SUBROUTINE not a FUNCTION" % name)


Expand All @@ -187,19 +186,19 @@ def syntax_error_undeclared_type(lineno: int, id_: str):
# ----------------------------------------
# Cannot assign a value to 'var'. It's not a variable
# ----------------------------------------
def syntax_error_cannot_assign_not_a_var(lineno, id_):
def syntax_error_cannot_assign_not_a_var(lineno: int, id_: str):
error(lineno, "Cannot assign a value to '%s'. It's not a variable" % id_)


# ----------------------------------------
# Cannot assign a value to 'var'. It's not a variable
# ----------------------------------------
def syntax_error_address_must_be_constant(lineno):
def syntax_error_address_must_be_constant(lineno: int):
error(lineno, 'Address must be a numeric constant expression')


# ----------------------------------------
# Cannot pass an array by value
# ----------------------------------------
def syntax_error_cannot_pass_array_by_value(lineno, id_):
def syntax_error_cannot_pass_array_by_value(lineno: int, id_: str):
error(lineno, "Array parameter '%s' must be passed ByRef" % id_)
2 changes: 1 addition & 1 deletion src/api/global_.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
# ----------------------------------------------------------------------
# The current filename being processed (changes with each #include)
# ----------------------------------------------------------------------
FILENAME = '(stdin)' # name of current file being parsed
FILENAME: str = '(stdin)' # name of current file being parsed

# ----------------------------------------------------------------------
# Global Symbol Table
Expand Down
5 changes: 3 additions & 2 deletions src/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from typing import Callable
from typing import IO
from typing import Iterable
from typing import Union

from . import constants
from . import global_
Expand Down Expand Up @@ -168,14 +169,14 @@ def get_final_value(symbol: symbols.SYMBOL) -> Any:
return result


def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
def timeout(seconds: Union[Callable[[], int], int] = 10, error_message=os.strerror(errno.ETIME)):
def decorator(func):
def _handle_timeout(signum, frame):
raise TimeoutError(error_message)

def wrapper(*args, **kwargs):
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(seconds)
signal.alarm(seconds() if isinstance(seconds, Callable) else seconds)
try:
result = func(*args, **kwargs)
finally:
Expand Down
16 changes: 15 additions & 1 deletion src/libzxbc/zxblex.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@
# ----------------------------------------------------------------------

import sys
import re

from src.ply import lex
from .keywords import KEYWORDS as reserved
from src import api
from src.api.errmsg import error
from src.api import global_

from .keywords import KEYWORDS as reserved


ASM = '' # Set to asm block when commenting
Expand Down Expand Up @@ -420,6 +424,16 @@ def t_asm_comment(t):
r';.*'


def t_asm_PREPROCLINE(t):
r'\#[ \t]*[Ll][Ii][Nn][Ee][ \t]+([0-9]+)(?:[ \t]+"((?:[^"]|"")*)")?[ \t]*\r?\n'
global ASM

ASM += t.value
match = re.match('#[ \t]*[Ll][Ii][Nn][Ee][ \t]+([0-9]+)(?:[ \t]+"((?:[^"]|"")*)")?[ \t]*\r?\n', t.value)
t.lexer.lineno = int(match.groups()[0])
global_.FILENAME = match.groups()[1] or global_.FILENAME


def t_asm_next(t):
r'.'
global ASM
Expand Down
Loading