mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
tweaks
This commit is contained in:
parent
534bf2f252
commit
614f90fc35
@ -13,7 +13,7 @@ from typing import Optional, Tuple, Set, Dict, Any, no_type_check
|
|||||||
import attr
|
import attr
|
||||||
from .plyparse import parse_file, ParseError, Module, Directive, Block, Subroutine, Scope, VarDef, LiteralValue, \
|
from .plyparse import parse_file, ParseError, Module, Directive, Block, Subroutine, Scope, VarDef, LiteralValue, \
|
||||||
SubCall, Goto, Return, Assignment, InlineAssembly, Register, Expression, ProgramFormat, ZpOptions,\
|
SubCall, Goto, Return, Assignment, InlineAssembly, Register, Expression, ProgramFormat, ZpOptions,\
|
||||||
SymbolName, process_constant_expression, process_dynamic_expression
|
SymbolName, Dereference, AddressOf
|
||||||
from .plylex import SourceRef, print_bold
|
from .plylex import SourceRef, print_bold
|
||||||
from .optimize import optimize
|
from .optimize import optimize
|
||||||
|
|
||||||
@ -74,7 +74,12 @@ class PlyParser:
|
|||||||
# process/simplify all expressions (constant folding etc)
|
# process/simplify all expressions (constant folding etc)
|
||||||
for block, parent in module.all_scopes():
|
for block, parent in module.all_scopes():
|
||||||
for node in block.nodes:
|
for node in block.nodes:
|
||||||
node.process_expressions(block.scope)
|
try:
|
||||||
|
node.process_expressions(block.scope)
|
||||||
|
except ParseError:
|
||||||
|
raise
|
||||||
|
except Exception as x:
|
||||||
|
self.handle_internal_error(x, "process_expressions of node {} in block {}".format(node, block.name))
|
||||||
|
|
||||||
@no_type_check
|
@no_type_check
|
||||||
def create_multiassigns(self, module: Module) -> None:
|
def create_multiassigns(self, module: Module) -> None:
|
||||||
@ -212,6 +217,10 @@ class PlyParser:
|
|||||||
self._get_subroutine_usages_from_expression(usages, expr.right, parent_scope)
|
self._get_subroutine_usages_from_expression(usages, expr.right, parent_scope)
|
||||||
elif isinstance(expr, LiteralValue):
|
elif isinstance(expr, LiteralValue):
|
||||||
return
|
return
|
||||||
|
elif isinstance(expr, Dereference):
|
||||||
|
return self._get_subroutine_usages_from_expression(usages, expr.location, parent_scope)
|
||||||
|
elif isinstance(expr, AddressOf):
|
||||||
|
return self._get_subroutine_usages_from_expression(usages, expr.name, parent_scope)
|
||||||
elif isinstance(expr, SymbolName):
|
elif isinstance(expr, SymbolName):
|
||||||
try:
|
try:
|
||||||
symbol = parent_scope[expr.name]
|
symbol = parent_scope[expr.name]
|
||||||
@ -357,6 +366,16 @@ class PlyParser:
|
|||||||
if sys.stderr.isatty():
|
if sys.stderr.isatty():
|
||||||
print("\x1b[0m", file=sys.stderr, end="", flush=True)
|
print("\x1b[0m", file=sys.stderr, end="", flush=True)
|
||||||
|
|
||||||
|
def handle_internal_error(self, exc: Exception, msg: str="") -> None:
|
||||||
|
if sys.stderr.isatty():
|
||||||
|
print("\x1b[1m", file=sys.stderr)
|
||||||
|
print("\nERROR: internal parser error: ", exc, file=sys.stderr)
|
||||||
|
if msg:
|
||||||
|
print(" Message:", msg, end="\n\n")
|
||||||
|
if sys.stderr.isatty():
|
||||||
|
print("\x1b[0m", file=sys.stderr, end="", flush=True)
|
||||||
|
raise exc
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
description = "Compiler for IL65 language, code name 'Sick'"
|
description = "Compiler for IL65 language, code name 'Sick'"
|
||||||
|
@ -213,7 +213,7 @@ class AssemblyGenerator:
|
|||||||
|
|
||||||
def generate_block_init(self, block: Block) -> None:
|
def generate_block_init(self, block: Block) -> None:
|
||||||
# generate the block initializer
|
# generate the block initializer
|
||||||
# @todo add a block initializer subroutine that can contain custom reset/init code? (static initializers)
|
# @todo add a block initializer subroutine that can contain custom reset/init code? (static initializer)
|
||||||
self.p("_il65_init_block\v; (re)set vars to initial values")
|
self.p("_il65_init_block\v; (re)set vars to initial values")
|
||||||
# @todo optimize init order (sort on value first to avoid needless register loads, etc)
|
# @todo optimize init order (sort on value first to avoid needless register loads, etc)
|
||||||
self.p("\vlda #0\n\vldx #0")
|
self.p("\vlda #0\n\vldx #0")
|
||||||
@ -240,6 +240,12 @@ class AssemblyGenerator:
|
|||||||
float_inits[variable.name] = (vname, fpbytes, vvalue)
|
float_inits[variable.name] = (vname, fpbytes, vvalue)
|
||||||
elif variable.datatype in STRING_DATATYPES:
|
elif variable.datatype in STRING_DATATYPES:
|
||||||
string_inits.append(variable)
|
string_inits.append(variable)
|
||||||
|
elif variable.datatype == DataType.BYTEARRAY:
|
||||||
|
pass # @todo init bytearray
|
||||||
|
elif variable.datatype == DataType.WORDARRAY:
|
||||||
|
pass # @todo init wordarray
|
||||||
|
elif variable.datatype == DataType.MATRIX:
|
||||||
|
pass # @todo init matrix
|
||||||
else:
|
else:
|
||||||
raise CodeError("weird var datatype", variable.datatype)
|
raise CodeError("weird var datatype", variable.datatype)
|
||||||
if float_inits:
|
if float_inits:
|
||||||
@ -330,8 +336,8 @@ class AssemblyGenerator:
|
|||||||
raise CodeError("unknown variable type " + str(vardef.datatype))
|
raise CodeError("unknown variable type " + str(vardef.datatype))
|
||||||
if string_vars:
|
if string_vars:
|
||||||
self.p("il65_string_vars_start")
|
self.p("il65_string_vars_start")
|
||||||
for sv in sorted(string_vars): # must be the same order as in the init routine!!!
|
for svar in sorted(string_vars, key=lambda v: v.name): # must be the same order as in the init routine!!!
|
||||||
self.p("{:s}\v.fill {:d}+1\t\t; {}".format(sv.name, len(sv.value), sv.datatype.name.lower()))
|
self.p("{:s}\v.fill {:d}+1\t\t; {}".format(svar.name, len(svar.value), svar.datatype.name.lower()))
|
||||||
self.p("")
|
self.p("")
|
||||||
|
|
||||||
def _generate_string_var(self, vardef: VarDef, init: bool=False) -> None:
|
def _generate_string_var(self, vardef: VarDef, init: bool=False) -> None:
|
||||||
@ -375,8 +381,7 @@ class AssemblyGenerator:
|
|||||||
assert rvalue is not None
|
assert rvalue is not None
|
||||||
if isinstance(rvalue, LiteralValue):
|
if isinstance(rvalue, LiteralValue):
|
||||||
rvalue = rvalue.value
|
rvalue = rvalue.value
|
||||||
print("ASSIGN", lvalue, lvalue.datatype, operator, rvalue)
|
print("ASSIGN", lvalue, lvalue.datatype, operator, rvalue) # @todo
|
||||||
# @todo
|
|
||||||
|
|
||||||
|
|
||||||
class Assembler64Tass:
|
class Assembler64Tass:
|
||||||
|
@ -107,7 +107,7 @@ class Optimizer:
|
|||||||
if block.scope:
|
if block.scope:
|
||||||
for stmt in block.scope.filter_nodes(Goto):
|
for stmt in block.scope.filter_nodes(Goto):
|
||||||
if isinstance(stmt.condition, Expression):
|
if isinstance(stmt.condition, Expression):
|
||||||
raise NotImplementedError("optimize goto conditionals", stmt.condition) # @todo
|
print("NOT IMPLEMENTED YET: optimize goto conditionals", stmt.condition) # @todo
|
||||||
# if cond and isinstance(cond.rvalue, (int, float)) and cond.rvalue.value == 0:
|
# if cond and isinstance(cond.rvalue, (int, float)) and cond.rvalue.value == 0:
|
||||||
# simplified = False
|
# simplified = False
|
||||||
# if cond.ifstatus in ("true", "ne"):
|
# if cond.ifstatus in ("true", "ne"):
|
||||||
|
@ -5,6 +5,7 @@ This is the lexer of the IL65 code, that generates a stream of tokens for the pa
|
|||||||
Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import ast
|
||||||
import sys
|
import sys
|
||||||
import ply.lex
|
import ply.lex
|
||||||
import attr
|
import attr
|
||||||
@ -258,7 +259,7 @@ def t_STRING(t):
|
|||||||
(?<!\\) # not preceded by a backslash
|
(?<!\\) # not preceded by a backslash
|
||||||
' # a literal double-quote
|
' # a literal double-quote
|
||||||
"""
|
"""
|
||||||
t.value = t.value[1:-1]
|
t.value = ast.literal_eval(t.value)
|
||||||
if len(t.value) == 1:
|
if len(t.value) == 1:
|
||||||
t.type = "CHARACTER"
|
t.type = "CHARACTER"
|
||||||
if len(t.value) == 2 and t.value[0] == '\\':
|
if len(t.value) == 2 and t.value[0] == '\\':
|
||||||
|
@ -624,31 +624,40 @@ def process_constant_expression(expr: Any, sourceref: SourceRef, symbolscope: Sc
|
|||||||
if isinstance(value, VarDef):
|
if isinstance(value, VarDef):
|
||||||
if value.vartype == VarType.MEMORY:
|
if value.vartype == VarType.MEMORY:
|
||||||
return value.value
|
return value.value
|
||||||
raise ParseError("can't take the address of this {}".format(value.__class__.__name__), expr.name.sourceref)
|
raise ExpressionEvaluationError("taking the address of this {} isn't a constant".format(value.__class__.__name__), expr.name.sourceref)
|
||||||
else:
|
else:
|
||||||
raise ExpressionEvaluationError("constant address required, not {}".format(value.__class__.__name__), expr.name.sourceref)
|
raise ExpressionEvaluationError("constant address required, not {}".format(value.__class__.__name__), expr.name.sourceref)
|
||||||
except LookupError as x:
|
except LookupError as x:
|
||||||
raise ParseError(str(x), expr.sourceref) from None
|
raise ParseError(str(x), expr.sourceref) from None
|
||||||
elif isinstance(expr, SubCall):
|
elif isinstance(expr, SubCall):
|
||||||
if isinstance(expr.target, CallTarget):
|
if isinstance(expr.target, CallTarget):
|
||||||
funcname = expr.target.target.name
|
print("CALLTARGET", expr.target.address_of, expr.target.target) # XXX
|
||||||
if funcname in math_functions or funcname in builtin_functions:
|
target = expr.target.target
|
||||||
if isinstance(expr.target.target, SymbolName):
|
if isinstance(target, SymbolName): # 'function(1,2,3)'
|
||||||
func_args = []
|
funcname = target.name
|
||||||
for a in (process_constant_expression(callarg.value, sourceref, symbolscope) for callarg in expr.arguments):
|
if funcname in math_functions or funcname in builtin_functions:
|
||||||
if isinstance(a, LiteralValue):
|
if isinstance(expr.target.target, SymbolName):
|
||||||
func_args.append(a.value)
|
func_args = []
|
||||||
else:
|
for a in (process_constant_expression(callarg.value, sourceref, symbolscope) for callarg in expr.arguments):
|
||||||
func_args.append(a)
|
if isinstance(a, LiteralValue):
|
||||||
func = math_functions.get(funcname, builtin_functions.get(funcname))
|
func_args.append(a.value)
|
||||||
try:
|
else:
|
||||||
return func(*func_args)
|
func_args.append(a)
|
||||||
except Exception as x:
|
func = math_functions.get(funcname, builtin_functions.get(funcname))
|
||||||
raise ExpressionEvaluationError(str(x), expr.sourceref)
|
try:
|
||||||
|
return func(*func_args)
|
||||||
|
except Exception as x:
|
||||||
|
raise ExpressionEvaluationError(str(x), expr.sourceref)
|
||||||
|
else:
|
||||||
|
raise ParseError("symbol name required, not {}".format(expr.target.__class__.__name__), expr.sourceref)
|
||||||
else:
|
else:
|
||||||
raise ParseError("symbol name required, not {}".format(expr.target.__class__.__name__), expr.sourceref)
|
raise ExpressionEvaluationError("can only use math- or builtin function", expr.sourceref)
|
||||||
|
elif isinstance(target, Dereference): # '[...](1,2,3)'
|
||||||
|
return None # XXX
|
||||||
|
elif isinstance(target, int): # '64738()'
|
||||||
|
return None # XXX
|
||||||
else:
|
else:
|
||||||
raise ExpressionEvaluationError("can only use math- or builtin function", expr.sourceref)
|
raise NotImplementedError("weird call target", target) # XXX
|
||||||
else:
|
else:
|
||||||
raise ParseError("function name required, not {}".format(expr.target.__class__.__name__), expr.sourceref)
|
raise ParseError("function name required, not {}".format(expr.target.__class__.__name__), expr.sourceref)
|
||||||
elif not isinstance(expr, Expression):
|
elif not isinstance(expr, Expression):
|
||||||
@ -707,6 +716,8 @@ def process_dynamic_expression(expr: Any, sourceref: SourceRef, symbolscope: Sco
|
|||||||
return expr
|
return expr
|
||||||
elif isinstance(expr, Register):
|
elif isinstance(expr, Register):
|
||||||
return expr
|
return expr
|
||||||
|
elif isinstance(expr, Dereference):
|
||||||
|
return expr
|
||||||
elif not isinstance(expr, Expression):
|
elif not isinstance(expr, Expression):
|
||||||
raise ParseError("expression required, not {}".format(expr.__class__.__name__), expr.sourceref)
|
raise ParseError("expression required, not {}".format(expr.__class__.__name__), expr.sourceref)
|
||||||
if expr.unary:
|
if expr.unary:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from il65.plylex import lexer, tokens, find_tok_column, literals, reserved, SourceRef
|
from il65.plylex import lexer, tokens, find_tok_column, literals, reserved, SourceRef
|
||||||
from il65.plyparse import parser, TokenFilter, Module, Subroutine, Block, Return, Scope, VarDef, Expression, LiteralValue, Label
|
from il65.plyparse import parser, TokenFilter, Module, Subroutine, Block, Return, Scope, \
|
||||||
|
VarDef, Expression, LiteralValue, Label, SubCall, CallTarget, SymbolName
|
||||||
|
|
||||||
|
|
||||||
def test_lexer_definitions():
|
def test_lexer_definitions():
|
||||||
@ -13,7 +14,7 @@ def test_lexer_definitions():
|
|||||||
assert "if_cc" in reserved
|
assert "if_cc" in reserved
|
||||||
|
|
||||||
|
|
||||||
test_source = """ %output prg, sys
|
test_source_1 = """ %output prg, sys
|
||||||
|
|
||||||
; c1
|
; c1
|
||||||
|
|
||||||
@ -40,8 +41,9 @@ test_source = """ %output prg, sys
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test_lexer():
|
def test_lexer():
|
||||||
lexer.input(test_source)
|
lexer.input(test_source_1)
|
||||||
lexer.lineno = 1
|
lexer.lineno = 1
|
||||||
tokens = list(iter(lexer))
|
tokens = list(iter(lexer))
|
||||||
token_types = list(t.type for t in tokens)
|
token_types = list(t.type for t in tokens)
|
||||||
@ -64,8 +66,22 @@ def test_lexer():
|
|||||||
assert bool_token.value == True
|
assert bool_token.value == True
|
||||||
|
|
||||||
|
|
||||||
|
def test_lexer_strings():
|
||||||
|
lexer.input(r"'hello\tbye\n\n' '\n'")
|
||||||
|
lexer.lineno = 1
|
||||||
|
tokens = list(iter(lexer))
|
||||||
|
assert len(tokens) == 2
|
||||||
|
st = tokens[0]
|
||||||
|
assert st.type == "STRING"
|
||||||
|
assert st.value == "hello\tbye\n\n"
|
||||||
|
lexer.input(r"'hello\tbye\n\n'")
|
||||||
|
st = tokens[1]
|
||||||
|
assert st.type == "CHARACTER"
|
||||||
|
assert st.value == '\n'
|
||||||
|
|
||||||
|
|
||||||
def test_tokenfilter():
|
def test_tokenfilter():
|
||||||
lexer.input(test_source)
|
lexer.input(test_source_1)
|
||||||
lexer.lineno = 1
|
lexer.lineno = 1
|
||||||
filter = TokenFilter(lexer)
|
filter = TokenFilter(lexer)
|
||||||
tokens = []
|
tokens = []
|
||||||
@ -88,7 +104,7 @@ def test_parser():
|
|||||||
lexer.lineno = 1
|
lexer.lineno = 1
|
||||||
lexer.source_filename = "sourcefile"
|
lexer.source_filename = "sourcefile"
|
||||||
filter = TokenFilter(lexer)
|
filter = TokenFilter(lexer)
|
||||||
result = parser.parse(input=test_source, tokenfunc=filter.token)
|
result = parser.parse(input=test_source_1, tokenfunc=filter.token)
|
||||||
assert isinstance(result, Module)
|
assert isinstance(result, Module)
|
||||||
assert result.name == "sourcefile"
|
assert result.name == "sourcefile"
|
||||||
assert result.scope.name == "<sourcefile global scope>"
|
assert result.scope.name == "<sourcefile global scope>"
|
||||||
@ -135,3 +151,32 @@ def test_block_nodes():
|
|||||||
assert sub2.scope is not None
|
assert sub2.scope is not None
|
||||||
assert len(sub2.scope.nodes) > 0
|
assert len(sub2.scope.nodes) > 0
|
||||||
assert sub2.nodes is sub2.scope.nodes
|
assert sub2.nodes is sub2.scope.nodes
|
||||||
|
|
||||||
|
|
||||||
|
test_source_2 = """
|
||||||
|
~ {
|
||||||
|
999(1,2)
|
||||||
|
&zz()
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_parser_2():
|
||||||
|
lexer.lineno = 1
|
||||||
|
lexer.source_filename = "sourcefile"
|
||||||
|
filter = TokenFilter(lexer)
|
||||||
|
result = parser.parse(input=test_source_2, tokenfunc=filter.token)
|
||||||
|
block = result.nodes[0]
|
||||||
|
call = block.nodes[0]
|
||||||
|
assert isinstance(call, SubCall)
|
||||||
|
assert len(call.arguments) == 2
|
||||||
|
assert isinstance(call.target, CallTarget)
|
||||||
|
assert call.target.target == 999
|
||||||
|
assert call.target.address_of is False
|
||||||
|
call = block.nodes[1]
|
||||||
|
assert isinstance(call, SubCall)
|
||||||
|
assert len(call.arguments) == 0
|
||||||
|
assert isinstance(call.target, CallTarget)
|
||||||
|
assert isinstance(call.target.target, SymbolName)
|
||||||
|
assert call.target.target.name == "zz"
|
||||||
|
assert call.target.address_of is True
|
||||||
|
@ -50,6 +50,10 @@ bar: goto $c000
|
|||||||
; goto [AX()] % ; @todo error, must be return()
|
; goto [AX()] % ; @todo error, must be return()
|
||||||
goto [var1]
|
goto [var1]
|
||||||
goto [mem1] ; comment
|
goto [mem1] ; comment
|
||||||
|
goto $c000
|
||||||
|
goto 64738
|
||||||
|
64738(1,2) ; @todo jsr $64738 ??
|
||||||
|
return 9999() ; @todo jsr 9999 ??
|
||||||
return [AX]()
|
return [AX]()
|
||||||
return [var1] () ; comment
|
return [var1] () ; comment
|
||||||
return [mem1] ()
|
return [mem1] ()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
%output prg,basic
|
%output basic
|
||||||
|
|
||||||
%import c64lib
|
%import c64lib
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
; 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 initword0a = &ZP.zpmem1 ; @todo should work, reference this symbols' generated address (@todo generate address for ZP)
|
||||||
var .word initword0 = &ZP.zpvar1
|
var .word initword0 = &ZP.zpvar1
|
||||||
var initbytea0 = &ZP.zpmem1
|
var initbytea0 = &ZP.zpmem1
|
||||||
var .word initworda1 = &ZP.zpvar1
|
var .word initworda1 = &ZP.zpvar1
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
%output prg,basic
|
%output basic
|
||||||
|
|
||||||
%import c64lib
|
%import c64lib
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
; var definitions and immediate primitive data type tests
|
; var definitions and immediate primitive data type tests
|
||||||
|
|
||||||
%output prg, basic
|
%output basic
|
||||||
%zp clobber
|
%zp clobber
|
||||||
|
|
||||||
%import c64lib
|
%import c64lib
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
%output prg,basic
|
%output basic
|
||||||
%import c64lib
|
%import c64lib
|
||||||
%import mathlib
|
%import mathlib
|
||||||
|
|
||||||
@ -95,4 +95,4 @@ sub goodbye ()->() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
; line 3 comment
|
; line 3 comment
|
||||||
|
|
||||||
|
|
||||||
%output basic , prg ; create a c-64 program with basic SYS call to launch it
|
%output basic ; create a c-64 program with basic SYS call to launch it
|
||||||
%zp restore , clobber ; clobber over the zp memory normally used by basic/kernel rom, frees up more zp
|
%zp restore , clobber ; clobber over the zp memory normally used by basic/kernel rom, frees up more zp
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
%output prg,basic ; create a c-64 program with basic SYS call to launch it
|
%output basic ; create a c-64 program with basic SYS call to launch it
|
||||||
|
|
||||||
|
|
||||||
%import c64lib ; searched in several locations and with .ill file extension added
|
%import c64lib ; searched in several locations and with .ill file extension added
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
%output prg,basic ; create a c-64 program with basic SYS to() launch it
|
%output basic ; create a c-64 program with basic SYS to() launch it
|
||||||
|
|
||||||
%import "c64lib.ill"
|
%import "c64lib.ill"
|
||||||
|
|
||||||
|
35
todo.ill
35
todo.ill
@ -1,29 +1,36 @@
|
|||||||
%output basic
|
%output basic
|
||||||
|
|
||||||
~ ZP {
|
~ ZP {
|
||||||
var zp1_1
|
var zp1_1 = 200
|
||||||
var zp1_2
|
var zp1_2 = 200
|
||||||
var zp1_3
|
var .word zp1_3 = $ff99
|
||||||
var zp1_4
|
var .word zp1_4 = $ee88
|
||||||
const zpc1_1
|
const zpc1_1 = 55
|
||||||
const zpc1_2
|
const .word zpc1_2 = 2333.54566
|
||||||
|
const .float zpc1_3 = 6.54566
|
||||||
}
|
}
|
||||||
|
|
||||||
~ ZP {
|
~ ZP {
|
||||||
var zp2_1
|
var zp2_1 = 100
|
||||||
var zp2_2
|
var zp2_2 = 100
|
||||||
var zp2_3
|
var .word zp2_3 = $55aa
|
||||||
var zp2_4
|
var .word zp2_4 = $66bb
|
||||||
const zpc2_1
|
const .text zpc2_1 = "hello"
|
||||||
const zpc2_2
|
const zpc2_2 = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
~ main {
|
~ main {
|
||||||
|
|
||||||
|
var .text hello_str = "hello there"
|
||||||
|
var .float float1 = 3.14
|
||||||
|
var .float float2 = 3.14
|
||||||
|
var .float float3 = 3.14
|
||||||
|
var .float float4 = 3.14
|
||||||
|
var .float float5 = 3.14
|
||||||
|
|
||||||
start:
|
start:
|
||||||
|
|
||||||
return
|
return 1.22, 46
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user