endl parsing

This commit is contained in:
Irmen de Jong 2018-01-05 22:52:23 +01:00
parent d92f91f22f
commit d9c62c2149
13 changed files with 1002 additions and 816 deletions

3
.gitignore vendored
View File

@ -14,3 +14,6 @@
*.asm *.asm
*.labels.txt *.labels.txt
.mypy_cache/ .mypy_cache/
__pycache__/
parser.out
parsetab.py

View File

@ -9,20 +9,17 @@ tokens = (
"FLOATINGPOINT", "FLOATINGPOINT",
"DOTTEDNAME", "DOTTEDNAME",
"NAME", "NAME",
"DOT",
"IS", "IS",
"CLOBBEREDREGISTER", "CLOBBEREDREGISTER",
"REGISTER", "REGISTER",
"COMMENT", "COMMENT",
"DIRECTIVE", "DIRECTIVE",
"AUGASSIGN", "AUGASSIGN",
"EQUAL", "EQUALS",
"NOTEQUAL", "NOTEQUALS",
"RARROW", "RARROW",
"RETURN", "RETURN",
"TILDE",
"VARTYPE", "VARTYPE",
"KEYWORD",
"SUB", "SUB",
"DATATYPE", "DATATYPE",
"CHARACTER", "CHARACTER",
@ -31,37 +28,47 @@ tokens = (
"GOTO", "GOTO",
"INCR", "INCR",
"DECR", "DECR",
"NOT",
"LT", "LT",
"GT", "GT",
"LE", "LE",
"GE", "GE",
"BITAND",
"BITOR",
"BITXOR",
"BITINVERT",
"LOGICAND",
"LOGICOR",
"LOGICNOT",
"POWER",
"LABEL", "LABEL",
"IF", "IF",
"ADDRESSOF",
"PRESERVEREGS", "PRESERVEREGS",
"INLINEASM", "INLINEASM",
"ENDL"
) )
literals = ['+', '-', '*', '/', '(', ')', '[', ']', '{', '}', '.', ',', '!', '?', ':'] literals = ['+', '-', '*', '/', '(', ')', '[', ']', '{', '}', '.', ',', '!', '?', ':']
# regex rules for simple tokens # regex rules for simple tokens
t_ADDRESSOF = r"\#" t_BITAND = r"&"
t_BITOR = r"\|"
t_BITXOR = r"\^"
t_BITINVERT = r"~"
t_IS = r"=" t_IS = r"="
t_TILDE = r"~"
t_DIRECTIVE = r"%[a-z]+"
t_AUGASSIGN = r"\+=|-=|/=|\*=|<<=|>>=|&=|\|=|\^=" t_AUGASSIGN = r"\+=|-=|/=|\*=|<<=|>>=|&=|\|=|\^="
t_DECR = r"--" t_DECR = r"--"
t_INCR = r"\+\+" t_INCR = r"\+\+"
t_EQUAL = r"==" t_EQUALS = r"=="
t_NOTEQUAL = r"!=" t_NOTEQUALS = r"!="
t_LT = r"<" t_LT = r"<"
t_GT = r">" t_GT = r">"
t_LE = r"<=" t_LE = r"<="
t_GE = r">=" t_GE = r">="
t_IF = "if(_[a-z]+)?" t_IF = "if(_[a-z]+)?"
t_RARROW = r"->" t_RARROW = r"->"
t_POWER = r"\*\*"
# ignore inline whitespace # ignore inline whitespace
t_ignore = " \t" t_ignore = " \t"
@ -83,7 +90,9 @@ reserved = {
"return": "RETURN", "return": "RETURN",
"true": "BOOLEAN", "true": "BOOLEAN",
"false": "BOOLEAN", "false": "BOOLEAN",
"not": "NOT", "not": "LOGICNOT",
"and": "LOGICAND",
"or": "LOGICOR",
"AX": "REGISTER", "AX": "REGISTER",
"AY": "REGISTER", "AY": "REGISTER",
"XY": "REGISTER", "XY": "REGISTER",
@ -96,12 +105,15 @@ reserved = {
"if": "IF", "if": "IF",
"if_true": "IF", "if_true": "IF",
"if_not": "IF", "if_not": "IF",
"if_zero": "IF",
"if_ne": "IF", "if_ne": "IF",
"if_eq": "IF", "if_eq": "IF",
"if_cc": "IF", "if_cc": "IF",
"if_cs": "IF", "if_cs": "IF",
"if_vc": "IF", "if_vc": "IF",
"if_vs": "IF", "if_vs": "IF",
"if_ge": "IF",
"if_le": "IF",
"if_gt": "IF", "if_gt": "IF",
"if_lt": "IF", "if_lt": "IF",
"if_pos": "IF", "if_pos": "IF",
@ -197,6 +209,12 @@ def t_NAME(t):
return t return t
def t_DIRECTIVE(t):
r"%[a-z]+"
t.value = t.value[1:]
return t
def t_STRING(t): def t_STRING(t):
r"""(?x) # verbose mode r"""(?x) # verbose mode
(?<!\\) # not preceded by a backslash (?<!\\) # not preceded by a backslash
@ -220,7 +238,7 @@ def t_STRING(t):
def t_FLOATINGPOINT(t): def t_FLOATINGPOINT(t):
r"[-+]? (?: (?: \d* \. \d+ ) | (?: \d+ \.? ) )(?: [Ee] [+-]? \d+ ) ?" r"((?: (?: \d* \. \d+ ) | (?: \d+ \.? ) )(?: [Ee] [+-]? \d+ ) ?)(?![a-z])"
try: try:
t.value = int(t.value) t.value = int(t.value)
t.type = "INTEGER" t.type = "INTEGER"
@ -230,7 +248,7 @@ def t_FLOATINGPOINT(t):
def t_INTEGER(t): def t_INTEGER(t):
r"([-+]?\$?[a-fA-F\d]+ | [-+]?[\$%]?\d+ | [-+]?%?[01]+)(?!\.)" r"\$?[a-fA-F\d]+ | [\$%]?\d+ | %?[01]+"
sign = 1 sign = 1
if t.value[0] in "+-": if t.value[0] in "+-":
sign = -1 if t.value[0] == "-" else 1 sign = -1 if t.value[0] == "-" else 1
@ -245,21 +263,20 @@ def t_INTEGER(t):
def t_COMMENT(t): def t_COMMENT(t):
r";[^\n]*" r"[ \t]*;[^\n]*" # dont eat newline
# don't include the \n at the end, that must be processed by t_newline return None # don't process comments
return None # ignore comments for now
def t_PRESERVEREGS(t): def t_PRESERVEREGS(t):
r"!\s*[AXY]{0,3}\s*" r"!\s*[AXY]{0,3}\s*(?!=)"
t.value = t.value[1:-1].strip() t.value = t.value[1:-1].strip()
return t return t
def t_newline(t): def t_ENDL(t):
r"\n+" r"\n+"
t.lexer.lineno += len(t.value) t.lexer.lineno += len(t.value)
return None # ignore white space tokens return t # end of lines are significant to the parser
def t_error(t): def t_error(t):

View File

@ -66,6 +66,12 @@ class SubCall(AstNode):
self.arguments = arguments self.arguments = arguments
class Return(AstNode):
def __init__(self, value, sourceref):
super().__init__(sourceref)
self.value = value
class InlineAssembly(AstNode): class InlineAssembly(AstNode):
def __init__(self, assembly, sourceref): def __init__(self, assembly, sourceref):
super().__init__(sourceref) super().__init__(sourceref)
@ -105,6 +111,27 @@ class Goto(AstNode):
self.condition = condition self.condition = condition
class Dereference(AstNode):
def __init__(self, location, datatype, sourceref):
super().__init__(sourceref)
self.location = location
self.datatype = datatype
class CallTarget(AstNode):
def __init__(self, target, address_of: bool, sourceref: SourceRef) -> None:
super().__init__(sourceref)
self.target = target
self.address_of = address_of
class CallArgument(AstNode):
def __init__(self, name, value, sourceref):
super().__init__(sourceref)
self.name = name
self.value = value
class UnaryOp(AstNode): class UnaryOp(AstNode):
def __init__(self, operator, operand, sourceref): def __init__(self, operator, operand, sourceref):
super().__init__(sourceref) super().__init__(sourceref)
@ -143,14 +170,15 @@ def p_module(p):
def p_module_elt(p): def p_module_elt(p):
"""module_elt : directive """module_elt : ENDL
| directive
| block """ | block """
p[0] = p[1] p[0] = p[1]
def p_directive(p): def p_directive(p):
"""directive : DIRECTIVE """directive : DIRECTIVE ENDL
| DIRECTIVE directive_args | DIRECTIVE directive_args ENDL
""" """
if len(p) == 2: if len(p) == 2:
p[0] = Directive(p[1], None, _token_sref(p, 1)) p[0] = Directive(p[1], None, _token_sref(p, 1))
@ -176,11 +204,25 @@ def p_directive_arg(p):
p[0] = p[1] p[0] = p[1]
def p_block_name_addr(p):
"""block : BITINVERT NAME INTEGER endl_opt scope"""
p[0] = Block(p[2], p[3], p[5], _token_sref(p, 1))
def p_block_name(p):
"""block : BITINVERT NAME endl_opt scope"""
p[0] = Block(p[2], None, p[4], _token_sref(p, 1))
def p_block(p): def p_block(p):
"""block : TILDE NAME INTEGER scope """block : BITINVERT endl_opt scope"""
| TILDE NAME empty scope p[0] = Block(None, None, p[3], _token_sref(p, 1))
| TILDE empty empty scope"""
p[0] = Block(p[2], p[3], p[4], _token_sref(p, 1))
def p_endl_opt(p):
"""endl_opt : empty
| ENDL"""
p[0] = p[1]
def p_scope(p): def p_scope(p):
@ -204,10 +246,11 @@ def p_scope_elements(p):
def p_scope_element(p): def p_scope_element(p):
"""scope_element : directive """scope_element : ENDL
| label
| directive
| vardef | vardef
| subroutine | subroutine
| label
| inlineasm | inlineasm
| statement""" | statement"""
p[0] = p[1] p[0] = p[1]
@ -219,26 +262,27 @@ def p_label(p):
def p_inlineasm(p): def p_inlineasm(p):
"""inlineasm : INLINEASM""" """inlineasm : INLINEASM ENDL"""
p[0] = InlineAssembly(p[1], _token_sref(p, 1)) p[0] = InlineAssembly(p[1], _token_sref(p, 1))
def p_vardef(p): def p_vardef(p):
"""vardef : VARTYPE type_opt NAME IS literal_value """vardef : VARTYPE type_opt NAME ENDL"""
| VARTYPE type_opt NAME"""
if len(p) == 4:
p[0] = VarDef(p[3], p[1], p[2], None, _token_sref(p, 1)) p[0] = VarDef(p[3], p[1], p[2], None, _token_sref(p, 1))
else:
def p_vardef_value(p):
"""vardef : VARTYPE type_opt NAME IS expression"""
p[0] = VarDef(p[3], p[1], p[2], p[5], _token_sref(p, 1)) p[0] = VarDef(p[3], p[1], p[2], p[5], _token_sref(p, 1))
def p_type_opt(p): def p_type_opt(p):
"""type_opt : DATATYPE """type_opt : DATATYPE '(' dimensions ')'
| DATATYPE '(' dimensions ')' | DATATYPE
| empty""" | empty"""
if len(p) == 4: if len(p) == 4:
p[0] = Datatype(p[1], p[3], _token_sref(p, 1)) p[0] = Datatype(p[1], p[3], _token_sref(p, 1))
elif p: elif len(p) == 2:
p[0] = Datatype(p[1], None, _token_sref(p, 1)) p[0] = Datatype(p[1], None, _token_sref(p, 1))
@ -261,7 +305,7 @@ def p_literal_value(p):
def p_subroutine(p): def p_subroutine(p):
"""subroutine : SUB NAME '(' sub_param_spec ')' RARROW '(' sub_result_spec ')' subroutine_body""" """subroutine : SUB NAME '(' sub_param_spec ')' RARROW '(' sub_result_spec ')' subroutine_body ENDL"""
p[0] = Subroutine(p[2], p[4], p[8], p[10], _token_sref(p, 1)) p[0] = Subroutine(p[2], p[4], p[8], p[10], _token_sref(p, 1))
@ -282,13 +326,11 @@ def p_sub_param_list(p):
def p_sub_param(p): def p_sub_param(p):
"""sub_param : LABEL REGISTER """sub_param : LABEL REGISTER
| empty REGISTER""" | REGISTER"""
if len(p) == 3:
p[0] = (p[1], p[2]) p[0] = (p[1], p[2])
elif len(p) == 2:
p[0] = (None, p[1])
def p_param_name(p):
"""param_name : NAME ':'"""
p[0] = p[1]
def p_sub_result_spec(p): def p_sub_result_spec(p):
@ -325,26 +367,24 @@ def p_subroutine_body(p):
def p_statement(p): def p_statement(p):
"""statement : assignment """statement : assignment ENDL
| subroutine_call | subroutine_call ENDL
| goto | goto ENDL
| conditional_goto | conditional_goto ENDL
| incrdecr | incrdecr ENDL
| RETURN | return ENDL
""" """
p[0] = p[1] p[0] = p[1]
def p_incrdecr(p): def p_incrdecr(p):
"""incrdecr : register INCR """incrdecr : assignment_target INCR
| register DECR | assignment_target DECR"""
| symbolname INCR
| symbolname DECR"""
p[0] = UnaryOp(p[2], p[1], _token_sref(p, 1)) p[0] = UnaryOp(p[2], p[1], _token_sref(p, 1))
def p_call_subroutine(p): def p_call_subroutine(p):
"""subroutine_call : symbolname preserveregs_opt '(' call_arguments_opt ')'""" """subroutine_call : calltarget preserveregs_opt '(' call_arguments_opt ')'"""
p[0] = SubCall(p[1], p[3], _token_sref(p, 1)) p[0] = SubCall(p[1], p[3], _token_sref(p, 1))
@ -375,9 +415,22 @@ def p_call_arguments(p):
def p_call_argument(p): def p_call_argument(p):
"""call_argument : literal_value """call_argument : expression
| register""" | register IS expression
p[0] = p[1] | NAME IS expression"""
if len(p) == 2:
p[0] = CallArgument(None, p[1], _token_sref(p, 1))
elif len(p) == 3:
p[0] = CallArgument(p[1], p[3], _token_sref(p, 1))
def p_return(p):
"""return : RETURN
| RETURN expression"""
if len(p) == 2:
p[0] = Return(None, _token_sref(p, 1))
elif len(p) == 4:
p[0] = Return(p[3], _token_sref(p, 1))
def p_register(p): def p_register(p):
@ -386,17 +439,43 @@ def p_register(p):
def p_goto(p): def p_goto(p):
"""goto : GOTO symbolname """goto : GOTO calltarget"""
| GOTO INTEGER"""
p[0] = Goto(p[2], None, None, _token_sref(p, 1)) p[0] = Goto(p[2], None, None, _token_sref(p, 1))
def p_conditional_goto(p): def p_conditional_goto_plain(p):
"""conditional_goto : IF GOTO symbolname""" """conditional_goto : IF GOTO calltarget"""
# @todo support conditional expression
p[0] = Goto(p[3], p[1], None, _token_sref(p, 1)) p[0] = Goto(p[3], p[1], None, _token_sref(p, 1))
def p_conditional_goto_expr(p):
"""conditional_goto : IF expression GOTO calltarget"""
p[0] = Goto(p[4], p[1], p[2], _token_sref(p, 1))
def p_calltarget(p):
"""calltarget : symbolname
| INTEGER
| BITAND symbolname
| dereference"""
if len(p) == 2:
p[0] = CallTarget(p[1], False, _token_sref(p, 1))
elif len(p) == 3:
p[0] = CallTarget(p[2], True, _token_sref(p, 1))
def p_dereference(p):
"""dereference : '[' dereference_operand ']' """
p[0] = Dereference(p[2][0], p[2][1], _token_sref(p, 1))
def p_dereference_operand(p):
"""dereference_operand : symbolname type_opt
| REGISTER type_opt
| INTEGER type_opt"""
p[0] = (p[1], p[2])
def p_symbolname(p): def p_symbolname(p):
"""symbolname : NAME """symbolname : NAME
| DOTTEDNAME""" | DOTTEDNAME"""
@ -404,8 +483,7 @@ def p_symbolname(p):
def p_assignment(p): def p_assignment(p):
"""assignment : assignment_lhs assignment_operator assignment_rhs""" """assignment : assignment_lhs assignment_operator expression"""
# @todo replace lhs/rhs by expressions
p[0] = Assignment(p[1], p[2], p[3], _token_sref(p, 1)) p[0] = Assignment(p[1], p[2], p[3], _token_sref(p, 1))
@ -415,35 +493,76 @@ def p_assignment_operator(p):
p[0] = p[1] p[0] = p[1]
def p_unary_operator(p): precedence = (
"""unary_operator : '+' ('left', '+', '-'),
| '-' ('left', '*', '/'),
| NOT ('right', 'UNARY_MINUS', 'BITINVERT', "UNARY_ADDRESSOF"),
| ADDRESSOF""" ('left', "LT", "GT", "LE", "GE", "EQUALS", "NOTEQUALS"),
('nonassoc', "COMMENT"),
)
def p_expression(p):
"""expression : expression '+' expression
| expression '-' expression
| expression '*' expression
| expression '/' expression
| expression LT expression
| expression GT expression
| expression LE expression
| expression GE expression
| expression EQUALS expression
| expression NOTEQUALS expression"""
pass
def p_expression_uminus(p):
"""expression : '-' expression %prec UNARY_MINUS"""
pass
def p_expression_addressof(p):
"""expression : BITAND symbolname %prec UNARY_ADDRESSOF"""
pass
def p_unary_expression_bitinvert(p):
"""expression : BITINVERT expression"""
pass
def p_expression_group(p):
"""expression : '(' expression ')'"""
p[0] = p[2]
def p_expression_ass_rhs(p):
"""expression : expression_value"""
p[0] = p[1]
def p_expression_value(p):
"""expression_value : literal_value
| symbolname
| register
| subroutine_call
| dereference"""
p[0] = p[1] p[0] = p[1]
def p_assignment_lhs(p): def p_assignment_lhs(p):
"""assignment_lhs : register """assignment_lhs : assignment_target
| symbolname | assignment_lhs ',' assignment_target"""
| assignment_lhs ',' register
| assignment_lhs ',' symbolname"""
if len(p) == 2: if len(p) == 2:
p[0] = [p[1]] p[0] = [p[1]]
else: else:
p[0] = p[1] + [p[2]] p[0] = p[1] + [p[2]]
def p_assignment_rhs(p): def p_assignment_target(p):
"""assignment_rhs : literal_value """assignment_target : register
| symbolname | symbolname
| register | dereference"""
| subroutine_call"""
p[0] = p[1]
def p_term(p):
"""term : register"""
p[0] = p[1] p[0] = p[1]
@ -454,8 +573,8 @@ def p_empty(p):
def p_error(p): def p_error(p):
if p: if p:
sref = SourceRef("@todo-filename2", p.lineno, find_tok_column(p)) sref = SourceRef(p.lexer.source_filename, p.lineno, find_tok_column(p))
lexer.error_function("{}: before '{:.20s}' ({})", sref, str(p.value), repr(p)) p.lexer.error_function("{}: before '{:.20s}' ({})", sref, str(p.value), repr(p))
else: else:
lexer.error_function("{}: at end of input", "@todo-filename3") lexer.error_function("{}: at end of input", "@todo-filename3")
@ -469,19 +588,39 @@ def _token_sref(p, token_idx):
if last_cr < 0: if last_cr < 0:
last_cr = -1 last_cr = -1
column = (p.lexpos(token_idx) - last_cr) column = (p.lexpos(token_idx) - last_cr)
return SourceRef("@todo-filename", p.lineno(token_idx), column) return SourceRef(p.lexer.source_filename, p.lineno(token_idx), column)
precedence = ( class TokenFilter:
('nonassoc', "COMMENT"), def __init__(self, lexer):
) self.lexer = lexer
self.prev_was_EOL = False
assert "ENDL" in tokens
parser = yacc() def token(self):
# make sure we only ever emit ONE "ENDL" token in sequence
if self.prev_was_EOL:
# skip all EOLS that might follow
while True:
tok = self.lexer.token()
if not tok or tok.type != "ENDL":
break
self.prev_was_EOL = False
else:
tok = self.lexer.token()
self.prev_was_EOL = tok and tok.type == "ENDL"
return tok
parser = yacc(write_tables=True)
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
file = sys.stdin # open(sys.argv[1], "rU") file = sys.stdin # open(sys.argv[1], "rU")
result = parser.parse(input=file.read()) or Module(None, SourceRef("@todo-sfile", 1, 1)) lexer.source_filename = "derp"
print("RESULT") tokenfilter = TokenFilter(lexer)
print(str(result)) result = parser.parse(input=file.read(),
tokenfunc=tokenfilter.token) or Module(None, SourceRef(lexer.source_filename, 1, 1))
# print("RESULT:")
# print(str(result))

View File

@ -695,8 +695,9 @@ ascii_to_petscii_trans = str.maketrans({
class AstNode: class AstNode:
def __init__(self, sourceref: SourceRef) -> None: def __init__(self, sourceref: SourceRef, children: List['AstNode']=None) -> None:
self.sourceref = sourceref.copy() self.sourceref = sourceref.copy()
self.children = children or []
@property @property
def lineref(self) -> str: def lineref(self) -> str:

View File

@ -1,10 +1,12 @@
; call tests ; call tests
;output %output foobar
~ foo { ~ foo {
var .word var1 = 99 var .word var1 = 99
memory .word mem1 = $cff0 memory .word mem1 = $cff0
@ -20,44 +22,54 @@
sub sub3 (XY) -> (Y?) = $ddaa sub sub3 (XY) -> (Y?) = $ddaa
sub sub4 (string: XY, other : A) -> (Y?) = $dd22 sub sub4 (string: XY, other : A) -> (Y?) = $dd22
bar2:
bar: bar: goto $c000
goto var1 ; jumps to the address in var1
goto $c000 goto mem1 ; jumps to the address in mem1
goto &var1 ; strange, but jumps to the location in memory where var1 sits
goto &mem1 ; strange, but jumps to the location in mempory where mem1 sits (points to)
goto [var1]
goto [$c000.word] goto [$c000.word]
goto [var1] goto [var1]
goto [mem1] goto [mem1]
goto var1 ; jumps to the address in var1
goto mem1 ; jumps to the address in mem1
goto #var1 ; strange, but jumps to the location in memory where var1 sits
goto #mem1 ; strange, but jumps to the location in mempory where mem1 sits (points to)
; ---- ; ----
goto sub1 goto sub1
goto sub2 (1 ) ;goto sub2 (1 ) ; @todo error, must be return sub2(1) -> optimized in 'tail call'
goto sub3 (3) return sub2 ( )
goto sub3 (XY="hello") return sub2 ()
goto sub3 ("hello, there") return sub2 (1 )
goto sub4 (string="hello, there", other = 42) return sub3 (3)
goto sub4 ("hello", 42) return sub3 (XY="hello")
goto sub4 ("hello", other= 42) return sub3 ("hello, there")
goto sub4 (string="hello", other = 42) return sub4 (string="hello, there", other = 42)
goto bar () return sub4 ("hello", 42)
return sub4 ("hello", other= 42)
return sub4 (string="hello", other = 42)
return bar ()
goto [AX] goto [AX]
goto [AX] () ; goto [AX()] % ; @todo error, must be return()
goto [var1] goto [var1]
goto [var1] () ; comment
goto [mem1] ; comment goto [mem1] ; comment
goto [mem1] () return [AX]()
goto [$c2.word] return [var1] () ; comment
goto [$c2.word] () return [mem1] ()
goto [$c2dd.word]
goto [$c2dd.word] ( )
goto $c000 goto $c000
goto $c000 ( ) return $c000 ( )
goto $c2 goto $c2
goto $c2() return $c2()
goto [$c2.word]
return 33
return [$c2.word] ; @todo this as rvalue
; [ $c2.word (4) ] ;@ todo parse precedence
return [$c2.word] (4)
return [$c2.word] (4)
return [$c2.word] (4)
return [$c2.word] (4)
; return [$c2dd.word] ( ) ;@ todo parse precedence
goto [$c2dd.word]
%asm { %asm {
nop nop
@ -85,6 +97,8 @@ bar:
sub3 !AXY (81) sub3 !AXY (81)
bar!() bar!()
bar !()
[XY]! ()
[XY] ! () [XY] ! ()
[var1]!() [var1]!()
[mem1]!() [mem1]!()
@ -113,8 +127,9 @@ bar:
[AX]() [AX]()
[var1] ( ) [var1] ( )
[mem1] () [mem1] ()
[$c2.word]() A= [$c2.word(4)]
[$c2dd.word]() ;A= [$c2.word() ] ; @todo Precedence?
;A= [$c2dd.word() ] ; @todo Precedence?
$c000() $c000()
$c2() $c2()
@ -145,4 +160,5 @@ sub unused_sub ()->() {
return return
} }
} }

View File

@ -4,6 +4,7 @@
~ main { ~ main {
var .word value var .word value
memory .word memvalue = $8000 memory .word memvalue = $8000
@ -23,7 +24,7 @@ start:
if_gt goto label if_gt goto label
if_cc goto value if_cc goto value
;if_cc goto memvalue ;if_cc goto memvalue
if_cc goto #value if_cc goto &value
;if_cc goto #memvalue ;if_cc goto #memvalue
if_cc goto [value] if_cc goto [value]
;if_cc goto [memvalue] ;if_cc goto [memvalue]
@ -82,8 +83,8 @@ label4:
; @todo temporarily disabled until comparison operators are properly implemented: ; @todo temporarily disabled until comparison operators are properly implemented:
~ { ~ {
var bytevar = 22 + 23
var .text name = "?"*80 var .text name = "?"*80
var bytevar = 22
var bytevar2 = 23 var bytevar2 = 23
var .word wordvar = 22345 var .word wordvar = 22345
@ -142,3 +143,5 @@ label1:
label2: label2:
return return
} }

View File

@ -64,13 +64,15 @@
var .float initfloat4 = 1.70141183e+38 var .float initfloat4 = 1.70141183e+38
var .float initfloat5 = -1.70141183e+38 var .float initfloat5 = -1.70141183e+38
var .float initfloat6 = 1.234 var .float initfloat6 = 1.234
var .float (44) zzzz = 333
var .wordarray ( 10 ) uninit_wordarray
var .wordarray(10) init_wordarray = $1234
var .wordarray(10) init_wordarrayb = true
var .array( 10) uninit_bytearray var .array( 10) uninit_bytearray
var .array(10 ) init_bytearray =$12 var .array(10 ) init_bytearray =$12
var .array(10 ) init_bytearrayb =true var .array(10 ) init_bytearrayb =true
var .array(10 ) init_bytearrayc ='@' var .array(10 ) init_bytearrayc ='@'
var .wordarray( 10 ) uninit_wordarray
var .wordarray(10) init_wordarray = $1234
var .wordarray(10) init_wordarrayb = true
var .text text = "hello-null" var .text text = "hello-null"
var .ptext ptext = 'hello-pascal' var .ptext ptext = 'hello-pascal'
@ -111,25 +113,27 @@
const .pstext ctext6 = "constant-pstext" const .pstext ctext6 = "constant-pstext"
; taking the address of various things: ; taking the address of various things:
var .word vmemaddr1 = #membyte1 var .word vmemaddr1 = & membyte1
var .word vmemaddr2 = #memword1 var .word vmemaddr2 = & memword1
var .word vmemaddr3 = #memfloat var .word vmemaddr3 = & memfloat
var .word vmemaddr4 = #membytes var .word vmemaddr4 = & membytes
var .word vmemaddr5 = #memwords var .word vmemaddr5 = & memwords
var .word vmemaddr6 = #memmatrix var .word vmemaddr6 = & memmatrix
var .word vmemaddr8 = 100*sin(cbyte1) var .word vmemaddr8 = 100*sin(cbyte1)
var .word vmemaddr9 = cword2+$5432 var .word vmemaddr9 = cword2+$5432
var .word vmemaddr10 = cfloat2b var .word vmemaddr10 = cfloat2b
; taking the address of things from the ZP will work even when it is a var ; taking the address of things from the ZP will work even when it is a var
; because zp-vars get assigned a specific address (from a pool). Also, it's a byte. ; because zp-vars get assigned a specific address (from a pool). Also, it's a byte.
var .word initword0a = #ZP.zpmem1
var .word initword0 = #ZP.zpvar1 var .word initword0a = & ZP.zpmem1
var initbytea0 = #ZP.zpmem1 var .word initword0 = & ZP.zpvar1
var .word initworda1 = #ZP.zpvar1 var initbytea0 = & ZP.zpmem1
var .word initworda1 = & ZP.zpvar1
; (constant) expressions ; (constant) expressions
var expr_byte1b = -1-2-3-4-$22+0x80+ZP.zpconst var expr_byte1b = -1-2-3-4-$22+$80+ZP.zpconst
var .byte expr_fault2 = 1 + (8/3)+sin(33) + max(1,2,3) var .byte expr_fault2 = 1 + (8/3)+sin(33) + max(1,2,3)
@ -177,17 +181,18 @@ start:
XY = uninitbyte1 XY = uninitbyte1
XY = "text-immediate" XY = "text-immediate"
AY = "text-immediate" AY = "text-immediate"
AX = #"text-immediate" ; equivalent to simply assigning the string directly AX = &derp
AX = # "text-immediate" ; equivalent to simply assigning the string directly ; AX = &"text-immediate" ; equivalent to simply assigning the string directly
; AX = & "text-immediate" ; equivalent to simply assigning the string directly
AX = ctext3 AX = ctext3
AX = "" AX = ""
AX = XY AX = XY
AX = Y AX = Y
XY = membyte2 XY = membyte2
XY = #membyte2 XY = membyte2
XY = memword1 XY = memword1
XY = sin XY = sin
XY = #sin XY = &sin
[$c000] = A [$c000] = A
@ -211,7 +216,7 @@ start:
[$c000.word] = "" [$c000.word] = ""
[$c000.word] = uninitbyte1 [$c000.word] = uninitbyte1
[$c000.word] = membyte2 [$c000.word] = membyte2
[$c000.word] = #membyte2 [$c000.word] = &membyte2
[$c000.word] = [cword2] [$c000.word] = [cword2]
[$c000.word] = memword1 [$c000.word] = memword1
[$c000.float] = 65535 [$c000.float] = 65535
@ -225,7 +230,7 @@ start:
[$c112.word] = [$c223.byte] [$c112.word] = [$c223.byte]
[$c222.word] = [$c333.word] [$c222.word] = [$c333.word]
[$c333.word] = sin [$c333.word] = sin
[$c333.word] = #sin [$c333.word] = &sin
SC = 0 SC = 0
@ -261,7 +266,7 @@ start:
uninitfloat = 9.8765 uninitfloat = 9.8765
uninitfloat = '@' uninitfloat = '@'
initword1 = sin initword1 = sin
initword1 = #sin initword1 = &sin
membyte1 = A membyte1 = A
membyte1 = cbyte3 membyte1 = cbyte3
@ -276,7 +281,7 @@ start:
memword1 = 2233 memword1 = 2233
memfloat = 3.4567 memfloat = 3.4567
memword1 = sin memword1 = sin
memword1 = #sin memword1 = &sin
membyte1 = A membyte1 = A
memword1 = A memword1 = A
@ -304,7 +309,7 @@ start:
AY = "text-immediate" ; reuses existing AY = "text-immediate" ; reuses existing
AX = "another" AX = "another"
AX = "" AX = ""
[$c000.word] = "another" ; reuse ;*$c000.word = "another" ; reuse @ todo precedence?
[$c100.word] = "text-immediate" ; reuse ;*$c100.word = "text-immediate" ; reuse @ todo precedence?
[$c200.word] = "" ; reuse ;*$c200.word = "" ; reuse @ todo precedence?
} }

View File

@ -54,10 +54,10 @@ sub printflt (float: AY) -> (?) {
start: start:
; assign some float values to the memory ; assign some float values to the memory
AY = #flt_pi AY = &flt_pi
some_address = # flt_pi some_address = & flt_pi
some_address = 4123.2342342222 some_address = 4123.2342342222
[$c000.word] = # flt_pi [$c000.word] = & flt_pi
my_float ++ my_float ++
my_float += 1 my_float += 1
@ -70,47 +70,47 @@ start:
; print some floating points from source and compare them with ROM ; print some floating points from source and compare them with ROM
printflt(#flt_pi) printflt(&flt_pi)
printflt(#c64.FL_PIVAL) printflt(&c64.FL_PIVAL)
printflt(#flt_minus32768) printflt(&flt_minus32768)
printflt(#c64.FL_N32768) printflt(&c64.FL_N32768)
printflt(#flt_1) printflt(&flt_1)
printflt(#c64.FL_FONE) printflt(&c64.FL_FONE)
printflt(#flt_half_sqr2) printflt(&flt_half_sqr2)
printflt( # c64.FL_SQRHLF) printflt( & c64.FL_SQRHLF)
printflt(#flt_sqr2) printflt(&flt_sqr2)
printflt(#c64.FL_SQRTWO) printflt(&c64.FL_SQRTWO)
printflt(#flt_minus_half) printflt(&flt_minus_half)
printflt(#c64.FL_NEGHLF) printflt(&c64.FL_NEGHLF)
printflt(#flt_log_2) printflt(&flt_log_2)
printflt(#c64.FL_LOG2) printflt(&c64.FL_LOG2)
printflt(#flt_10) printflt(&flt_10)
printflt(#c64.FL_TENC) printflt(&c64.FL_TENC)
printflt(#flt_1e9) printflt(&flt_1e9)
printflt(#c64.FL_NZMIL) printflt(&c64.FL_NZMIL)
printflt(#flt_half) printflt(&flt_half)
printflt(#c64.FL_FHALF) printflt(&c64.FL_FHALF)
printflt(#flt_one_over_log_2) printflt(&flt_one_over_log_2)
printflt(#c64.FL_LOGEB2) printflt(&c64.FL_LOGEB2)
printflt(#flt_half_pi) printflt(&flt_half_pi)
printflt(#c64.FL_PIHALF) printflt(&c64.FL_PIHALF)
printflt(#flt_double_pi) printflt(&flt_double_pi)
printflt(#c64.FL_TWOPI) printflt(&c64.FL_TWOPI)
printflt(# flt_point25) printflt(& flt_point25)
printflt(#c64.FL_FR4) printflt(&c64.FL_FR4)
reg_to_float: reg_to_float:
c64.CHROUT!('\n') c64.CHROUT!('\n')
@ -120,25 +120,25 @@ reg_to_float:
Y=55 Y=55
my_float = A my_float = A
printflt(#my_float) printflt(&my_float)
my_float = X my_float = X
printflt(#my_float) printflt(&my_float)
my_float = Y my_float = Y
printflt(#my_float) printflt(&my_float)
XY = 11122 XY = 11122
my_float = XY my_float = XY
printflt(#my_float) printflt(&my_float)
AX = 33344 AX = 33344
my_float = AX my_float = AX
printflt(#my_float) printflt(&my_float)
AY = 55566 AY = 55566
my_float = AY my_float = AY
printflt(#my_float) printflt(&my_float)
return return
} }

View File

@ -11,7 +11,7 @@ start:
orig_irq = c64.CINV orig_irq = c64.CINV
SI = 1 SI = 1
c64.CINV = #irq_handler c64.CINV = &irq_handler
SI = 0 SI = 0
@ -20,7 +20,11 @@ start:
c64.CHROUT('\n') c64.CHROUT('\n')
blop: blop:
%breakpoint ; yeah! return
%breakpoint
return
; yeah!
c64scr.print_string("thank you, mr or mrs: ") c64scr.print_string("thank you, mr or mrs: ")
c64scr.print_string(name) c64scr.print_string(name)

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@ start: ;foo
Y = X Y = X
X = 66 X = 66
screen = 0 screen = 0
screen = border = cursor = X = Y = A = X = Y = A = border = cursor = border = cursor = 66 ; multi-assign! screen = border = cursor = X = Y = A = X = Y = A = border = cursor = border = cursor = 66 ; multi-assign! @todo ply parse
border = false border = false
border = true border = true
border = 0 border = 0
@ -98,7 +98,7 @@ sub customsub (Y)->() {
A=2 A=2
X=33 X=33
goto fidget.subroutine() return fidget.subroutine()
} }
@ -186,8 +186,6 @@ subroutine:
;[border2] = red ;[border2] = red
;[screen2] = white ;[screen2] = white
return $99 return $99
return ,$99
return ,,$99
} }

View File

@ -58,7 +58,7 @@ start:
c64.CHROUT('1') c64.CHROUT('1')
c64.CHROUT('2') c64.CHROUT('2')
c64scr.print_string(hello) c64scr.print_string(hello)
goto c64.CHROUT('!') return c64.CHROUT('!')
return return
@ -67,7 +67,7 @@ start:
~ global2 { ~ global2 {
make_screen_black: make_screen_black:
c64.EXTCOL = c64.BGCOL0 = 0 c64.EXTCOL = c64.BGCOL0 = 0 ; @todo ply parse multiassign
c64.COLOR = 3 c64.COLOR = 3
Y = true Y = true
return return

View File

@ -1,6 +1,6 @@
%output prg,basic ; create a c-64 program with basic SYS to() launch it %output prg,basic ; create a c-64 program with basic SYS to() launch it
%import c64lib.ill %import "c64lib.ill"
~ main ~ main
{ {
@ -53,7 +53,7 @@ start2:
~ global2 { ~ global2 {
make_screen_black: make_screen_black:
c64.EXTCOL = c64.BGCOL0 = 0 c64.EXTCOL = c64.BGCOL0 = 0 ; @todo ply parse multi assign
c64.COLOR = 3 c64.COLOR = 3
return return