Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Commit

Permalink
Merge pull request boriel-basic#642 from boriel/bugfix/macros_with_un…
Browse files Browse the repository at this point in the history
…derscore

fix: restart zxbpp macros table for ASM
  • Loading branch information
boriel committed Dec 29, 2022
2 parents e79e12d + 9ae7167 commit fbc9a52
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/api/symboltable/symboltable.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def leave_scope(self, show_warnings=True):
v.accessed = True # Parameters must always be present even if not used!
# byref is always marked as used: it can be used to return a value
if show_warnings and not v.byref:
warning_not_used(v.lineno, v.name, kind=kind)
warning_not_used(v.lineno, v.name, kind=kind, fname=v.filename)

for entry in self.current_scope.values(filter_by_opt=True): # Symbols of the current level
if entry.class_ == CLASS.unknown:
Expand Down
7 changes: 3 additions & 4 deletions src/arch/z80/translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
from src.symbols import sym as symbols
from src.symbols.id_ import ref
from src.symbols.type_ import Type
from src.zxbpp import zxbpp

__all__ = ["Translator", "VarTranslator", "FunctionTranslator"]

Expand Down Expand Up @@ -986,7 +985,7 @@ def default_value(cls, type_, expr): # TODO: This function must be moved to api

if expr.token in ("CONSTEXPR", "CONST"): # a constant expression like @label + 1
if type_ in (cls.TYPE(TYPE.float), cls.TYPE(TYPE.string)):
error(expr.lineno, "Can't convert non-numeric value to {0} at compile time".format(type_.name))
error(expr.lineno, f"Can't convert non-numeric value to {type_.name} at compile time")
return ["<ERROR>"]

val = Translator.traverse_const(expr)
Expand Down Expand Up @@ -1094,7 +1093,7 @@ def visit_LABEL(self, node):
def visit_VARDECL(self, node):
entry = node.entry
if not entry.accessed:
src.api.errmsg.warning_not_used(entry.lineno, entry.name)
src.api.errmsg.warning_not_used(entry.lineno, entry.name, fname=entry.filename)
if self.O_LEVEL > 1: # HINT: Unused vars not compiled
return

Expand Down Expand Up @@ -1412,7 +1411,7 @@ def visit_FUNCTION(self, node):
bound_ptrs[1] = ubound_label

if bound_ptrs:
zxbpp.ID_TABLE.define("__ZXB_USE_LOCAL_ARRAY_WITH_BOUNDS__", lineno=0)
OPTIONS["__DEFINES"].value["__ZXB_USE_LOCAL_ARRAY_WITH_BOUNDS__"] = ""

if local_var.lbound_used:
l = ["%04X" % bound.lower for bound in local_var.bounds]
Expand Down
2 changes: 2 additions & 0 deletions src/symbols/id_/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
from src.symbols.id_._id import SymbolID

__all__ = ["SymbolID"]
28 changes: 14 additions & 14 deletions src/zxbc/args_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
from src.api.config import OPTIONS
from src.api.utils import open_file
from src.zxbc import args_parser, zxbparser
from src.zxbpp import zxbpp

__all__ = ["FileType", "parse_options"]
__all__ = ["FileType", "parse_options", "set_option_defines"]


class FileType:
Expand Down Expand Up @@ -88,7 +87,6 @@ def parse_options(args: List[str] = None):
name = macro[0]
val = "".join(macro[1:])
OPTIONS.__DEFINES[name] = val
zxbpp.ID_TABLE.define(name, value=val, lineno=0)

if OPTIONS.sinclair:
OPTIONS.array_base = 1
Expand Down Expand Up @@ -128,17 +126,7 @@ def parse_options(args: List[str] = None):
parser.error("No such file or directory: '%s'" % args[0])
return 2

if OPTIONS.memory_check:
OPTIONS.__DEFINES["__MEMORY_CHECK__"] = ""
zxbpp.ID_TABLE.define("__MEMORY_CHECK__", lineno=0)

if OPTIONS.array_check:
OPTIONS.__DEFINES["__CHECK_ARRAY_BOUNDARY__"] = ""
zxbpp.ID_TABLE.define("__CHECK_ARRAY_BOUNDARY__", lineno=0)

if OPTIONS.enable_break:
OPTIONS.__DEFINES["__ENABLE_BREAK__"] = ""
zxbpp.ID_TABLE.define("__ENABLE_BREAK__", lineno=0)
set_option_defines()

OPTIONS.include_path = options.include_path
OPTIONS.input_filename = zxbparser.FILENAME = os.path.basename(args[0])
Expand All @@ -152,3 +140,15 @@ def parse_options(args: List[str] = None):
OPTIONS.stderr = open_file(OPTIONS.stderr_filename, "wt", "utf-8")

return options


def set_option_defines():
"""Sets some macros automatically, according to options"""
if OPTIONS.memory_check:
OPTIONS.__DEFINES["__MEMORY_CHECK__"] = ""

if OPTIONS.array_check:
OPTIONS.__DEFINES["__CHECK_ARRAY_BOUNDARY__"] = ""

if OPTIONS.enable_break:
OPTIONS.__DEFINES["__ENABLE_BREAK__"] = ""
16 changes: 13 additions & 3 deletions src/zxbc/zxbc.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from src.api.utils import open_file
from src.zxbasm import asmparse
from src.zxbc import zxblex, zxbparser
from src.zxbc.args_config import FileType, parse_options
from src.zxbc.args_config import FileType, parse_options, set_option_defines
from src.zxbpp import zxbpp
from src.zxbpp.zxbpp import PreprocMode

Expand Down Expand Up @@ -69,18 +69,18 @@ def main(args=None, emitter=None):
"""
# region [Initialization]
config.init()
zxbpp.init()
zxbparser.init()
arch.target.backend.init()
arch.target.Translator.reset()
asmparse.init()
# endregion

options = parse_options(args)
zxbpp.init()
arch.set_target_arch(OPTIONS.architecture)
arch.target.Translator.reset()
backend = arch.target.backend
backend.init() # Must reinitialize it again
# endregion

args = [options.PROGRAM] # Strip out other options, because they're already set in the OPTIONS container
input_filename = options.PROGRAM
Expand Down Expand Up @@ -121,6 +121,10 @@ def main(args=None, emitter=None):
func_visitor = arch.target.FunctionTranslator(gl.FUNCTIONS)
func_visitor.start()

if gl.has_errors:
debug.__DEBUG__("exiting due to errors.")
return 1 # Exit with errors

# Emits data lines
translator.emit_data_blocks()
# Emits default constant strings
Expand All @@ -130,6 +134,10 @@ def main(args=None, emitter=None):
# Signals end of user code
translator.ic_inline(";; --- end of user code ---")

if gl.has_errors:
debug.__DEBUG__("exiting due to errors.")
return 1 # Exit with errors

if OPTIONS.emit_backend:
with open_file(OPTIONS.output_filename, "wt", "utf-8") as output_file:
for quad in translator.dumpMemory(backend.MEMORY):
Expand Down Expand Up @@ -157,6 +165,8 @@ def main(args=None, emitter=None):
asm_output = "\n".join(asm_output)

# Now filter them against the preprocessor again
set_option_defines() # Needed for zxbpp.init()
zxbpp.reset_id_table()
zxbpp.setMode(zxbpp.PreprocMode.ASM)
zxbpp.OUTPUT = ""
zxbpp.filter_(asm_output, filename=input_filename)
Expand Down
15 changes: 2 additions & 13 deletions src/zxbc/zxbparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
is_string,
is_unsigned,
)
from src.api.config import OPTIONS
from src.api.constants import CLASS, CONVENTION, SCOPE, LoopType
from src.api.debug import __DEBUG__
from src.api.errmsg import error, warning
Expand All @@ -59,18 +60,6 @@
from src.symbols.type_ import Type as TYPE
from src.zxbc import zxblex
from src.zxbc.zxblex import tokens # noqa
from src.zxbpp import zxbpp

# PI Constant
# PI = 3.1415927 is ZX Spectrum PI representation
# But a better one is 3.141592654, so take it from math


# ----------------------------------------------------------------------
# Global configuration. Must be refreshed with init() i
# if api.config.init() is called
# ----------------------------------------------------------------------
OPTIONS = src.api.config.OPTIONS

# ----------------------------------------------------------------------
# Function level entry ID in which scope we are into. If the list
Expand Down Expand Up @@ -517,7 +506,7 @@ def p_start(p):
make_label(gl.ZXBASIC_USER_DATA_LEN, 0)

if PRINT_IS_USED:
zxbpp.ID_TABLE.define("___PRINT_IS_USED___", 1)
OPTIONS.__DEFINES["___PRINT_IS_USED___"] = 1

if zxblex.IN_STATE:
p.type = "NEWLINE"
Expand Down
28 changes: 21 additions & 7 deletions src/zxbpp/zxbpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
from src.api import config, global_, utils
from src.ply import yacc
from src.zxbpp import zxbasmpplex, zxbpplex

from .prepro import ID, Arg, ArgList, DefinesTable, MacroCall, output
from .prepro.exceptions import PreprocError
from .prepro.operators import Concatenation, Stringizing
from .prepro.output import error, warning
from .zxbpplex import tokens # noqa
from src.zxbpp.prepro import ID, Arg, ArgList, DefinesTable, MacroCall, output
from src.zxbpp.prepro.builtinmacro import BuiltinMacro
from src.zxbpp.prepro.exceptions import PreprocError
from src.zxbpp.prepro.operators import Concatenation, Stringizing
from src.zxbpp.prepro.output import error, warning
from src.zxbpp.zxbpplex import tokens # noqa


@unique
Expand Down Expand Up @@ -102,6 +102,19 @@ def remove_spaces(x: str) -> str:
return x.strip(" \t") or " "


def reset_id_table():
"""Initializes ID_TABLE with default DEFINES
(i.e. those that derives from OPTIONS)
"""
ID_TABLE.clear()

for name, val in config.OPTIONS.__DEFINES.items():
ID_TABLE.define(name, value=val, lineno=0)

for macro_name, macro_func in LEXER.builtin_macros.items():
LEXER.defines_table[macro_name] = BuiltinMacro(macro_name=macro_name, func=macro_func)


def init():
"""Initializes the preprocessor"""
global OUTPUT
Expand All @@ -120,9 +133,10 @@ def init():
global_.has_errors = 0
global_.error_msg_cache.clear()
parser.defaulted_states = {}
ID_TABLE.clear()
del output.CURRENT_FILE[:]

reset_id_table()


def get_include_path() -> str:
"""Default include path using a tricky sys calls."""
Expand Down
44 changes: 44 additions & 0 deletions tests/functional/zx48k/macro_under.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
org 32768
.core.__START_PROGRAM:
di
push ix
push iy
exx
push hl
exx
ld hl, 0
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
.core.ZXBASIC_USER_DATA:
; Defines USER DATA Length in bytes
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
_x:
DEFB 00
_y:
DEFB 00
.core.ZXBASIC_USER_DATA_END:
.core.__MAIN_PROGRAM__:
ld a, (_x)
ld (_y), a
ld hl, 0
ld b, h
ld c, l
.core.__END_PROGRAM:
di
ld hl, (.core.__CALL_BACK__)
ld sp, hl
exx
pop hl
exx
pop iy
pop ix
ei
ret
;; --- end of user code ---
END
4 changes: 4 additions & 0 deletions tests/functional/zx48k/macro_under.bas
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#define _x 0
dim x, y as ubyte
y = x

0 comments on commit fbc9a52

Please sign in to comment.