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
13 changes: 7 additions & 6 deletions symbols/builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@


class SymbolBUILTIN(Symbol):
''' Defines an BUILTIN function e.g. INKEY$(), RND() or LEN
'''
""" Defines an BUILTIN function e.g. INKEY$(), RND() or LEN
"""
def __init__(self, lineno, fname, type_=None, *operands):
assert isinstance(lineno, int)
assert type_ is None or isinstance(type_, SymbolTYPE)
Expand Down Expand Up @@ -60,24 +60,25 @@ def operands(self, value):

@property
def size(self):
''' sizeof(type)
'''
""" sizeof(type)
"""
if self.type_ is None:
return 0
return self.type_.size

@classmethod
def make_node(cls, lineno, fname, func=None, type_=None, *operands):
''' Creates a node for a unary operation. E.g. -x or LEN(a$)
""" Creates a node for a unary operation. E.g. -x or LEN(a$)

Parameters:
-func: function used on constant folding when possible
-type_: the resulting type (by default, the same as the argument).
For example, for LEN (str$), result type is 'u16'
and arg type is 'string'
'''
"""
if func is not None and len(operands) == 1: # Try constant-folding
if is_number(operands[0]) or is_string(operands[0]): # e.g. ABS(-5)
print(func.__name__)
return SymbolNUMBER(func(operands[0].value), type_=type_, lineno=lineno)

return cls(lineno, fname, type_, *operands)
113 changes: 113 additions & 0 deletions tests/functional/constrig.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
org 32768
__START_PROGRAM:
di
push ix
push iy
exx
push hl
exx
ld hl, 0
add hl, sp
ld (__CALL_BACK__), hl
ei
ld a, 07Fh
ld de, 099B3h
ld bc, 0F5DBh
ld hl, _a
call __STOREF
ld a, 080h
ld de, 0BBEFh
ld bc, 01EA0h
ld hl, _a
call __STOREF
ld a, 07Fh
ld de, 0C93Fh
ld bc, 064B0h
ld hl, _a
call __STOREF
ld a, 07Dh
ld de, 0244Dh
ld bc, 0B093h
ld hl, _a
call __STOREF
ld a, 081h
ld de, 03D3Ch
ld bc, 06791h
ld hl, _a
call __STOREF
ld a, 07Fh
ld de, 03915h
ld bc, 030D3h
ld hl, _a
call __STOREF
ld a, 081h
ld de, 05A20h
ld bc, 07589h
ld hl, _a
call __STOREF
ld a, 086h
ld de, 07604h
ld bc, 00939h
ld hl, _a
call __STOREF
ld a, 081h
ld de, 0776Fh
ld bc, 08B50h
ld hl, _a
call __STOREF
ld hl, 0
ld b, h
ld c, l
__END_PROGRAM:
di
ld hl, (__CALL_BACK__)
ld sp, hl
exx
pop hl
exx
pop iy
pop ix
ei
ret
__CALL_BACK__:
DEFW 0
#line 1 "storef.asm"

__PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL)
push de
ex de, hl ; DE <- HL
push ix
pop hl ; HL <- IX
add hl, de ; HL <- IX + HL
pop de

__ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register
ex af, af'
ld a, (hl)
inc hl
ld h, (hl)
ld l, a ; HL = (HL)
ex af, af'

__STOREF: ; Stores the given FP number in A EDCB at address HL
ld (hl), a
inc hl
ld (hl), e
inc hl
ld (hl), d
inc hl
ld (hl), c
inc hl
ld (hl), b
ret

#line 63 "constrig.bas"

ZXBASIC_USER_DATA:
_a:
DEFB 00, 00, 00, 00, 00
; Defines DATA END --> HEAP size is 0
ZXBASIC_USER_DATA_END EQU ZXBASIC_MEM_HEAP
; Defines USER DATA Length in bytes
ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA
END
13 changes: 13 additions & 0 deletions tests/functional/constrig.bas
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

DIM a as Float

a = SIN(3.5)
a = COS(3.5)
a = TAN(3.5)
a = ASN(0.1)
a = ACS(0.1)
a = ATN(0.3)
a = LN(3.5)
a = EXP(3.5)
a = SQR(3.5)

15 changes: 11 additions & 4 deletions zxbparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,6 @@ def make_builtin(lineno, fname, operands, func=None, type_=None):
operands = []
assert isinstance(operands, Symbol) or isinstance(operands, tuple) or isinstance(operands, list)
# TODO: In the future, builtin functions will be implemented in an external library, like POINT or ATTR
# HINT: They are not yet, because Sinclair BASIC grammar allows not to use parenthesis e.g. SIN x = SIN(x)
# HINT: which requires syntactical changes in the parser
__DEBUG__('Creating BUILTIN "{}"'.format(fname), 1)
if not isinstance(operands, collections.Iterable):
operands = [operands]
Expand Down Expand Up @@ -3211,12 +3209,21 @@ def p_sgn(p):
# ----------------------------------------
# Trigonometrics and LN, EXP, SQR
# ----------------------------------------
def p_expr_sin(p):
def p_expr_trig(p):
""" bexpr : math_fn bexpr %prec UMINUS
"""
p[0] = make_builtin(p.lineno(1), p[1],
make_typecast(TYPE.float_, p[2], p.lineno(1)),
lambda x: math.sin(x))
{'SIN': math.sin,
'COS': math.cos,
'TAN': math.tan,
'ASN': math.asin,
'ACS': math.acos,
'ATN': math.atan,
'LN': lambda y: math.log(y, math.exp(1)), # LN(x)
'EXP': math.exp,
'SQR': math.sqrt
}[p[1]])


def p_math_fn(p):
Expand Down