mirror of
https://github.com/irmen/prog8.git
synced 2024-08-17 02:28:56 +00:00
var dimensions check
This commit is contained in:
parent
62dfdace71
commit
1df28c8091
@ -81,7 +81,8 @@ class PlyParser:
|
|||||||
if not module.scope.nodes:
|
if not module.scope.nodes:
|
||||||
return
|
return
|
||||||
zpnode = module.scope.nodes[0]
|
zpnode = module.scope.nodes[0]
|
||||||
assert zpnode.name == "ZP", "first node should be the (only) ZP"
|
if zpnode.name != "ZP":
|
||||||
|
return
|
||||||
zeropage = Zeropage(module.zp_options)
|
zeropage = Zeropage(module.zp_options)
|
||||||
for vardef in zpnode.scope.filter_nodes(VarDef):
|
for vardef in zpnode.scope.filter_nodes(VarDef):
|
||||||
try:
|
try:
|
||||||
@ -94,9 +95,11 @@ class PlyParser:
|
|||||||
# process/simplify all expressions (constant folding etc)
|
# process/simplify all expressions (constant folding etc)
|
||||||
encountered_blocks = set()
|
encountered_blocks = set()
|
||||||
for block, parent in module.all_scopes():
|
for block, parent in module.all_scopes():
|
||||||
if block.name in encountered_blocks:
|
parentname = (parent.name + ".") if parent else ""
|
||||||
raise ValueError("block names not unique:", block.name)
|
blockname = parentname + block.name
|
||||||
encountered_blocks.add(block.name)
|
if blockname in encountered_blocks:
|
||||||
|
raise ValueError("block names not unique:", blockname)
|
||||||
|
encountered_blocks.add(blockname)
|
||||||
for node in block.nodes:
|
for node in block.nodes:
|
||||||
try:
|
try:
|
||||||
node.process_expressions(block.scope)
|
node.process_expressions(block.scope)
|
||||||
@ -323,7 +326,7 @@ class PlyParser:
|
|||||||
if sub_node.name not in {"asmbinary", "asminclude", "breakpoint", "saveregisters"}:
|
if sub_node.name not in {"asmbinary", "asminclude", "breakpoint", "saveregisters"}:
|
||||||
raise ParseError("invalid directive in " + node.__class__.__name__.lower(), sub_node.sourceref)
|
raise ParseError("invalid directive in " + node.__class__.__name__.lower(), sub_node.sourceref)
|
||||||
if sub_node.name == "saveregisters" and not first_node:
|
if sub_node.name == "saveregisters" and not first_node:
|
||||||
raise ParseError("saveregisters directive should be the first", sub_node.sourceref)
|
raise ParseError("saveregisters directive must be the first", sub_node.sourceref)
|
||||||
first_node = False
|
first_node = False
|
||||||
|
|
||||||
def process_imports(self, module: Module) -> None:
|
def process_imports(self, module: Module) -> None:
|
||||||
|
@ -68,10 +68,13 @@ FLOAT_MAX_NEGATIVE = -1.7014118345e+38
|
|||||||
|
|
||||||
|
|
||||||
def to_hex(number: int) -> str:
|
def to_hex(number: int) -> str:
|
||||||
# 0..255 -> "$00".."$ff"
|
# 0..15 -> "0".."15"
|
||||||
|
# 16..255 -> "$10".."$ff"
|
||||||
# 256..65536 -> "$0100".."$ffff"
|
# 256..65536 -> "$0100".."$ffff"
|
||||||
if number is None:
|
if number is None:
|
||||||
raise ValueError("number")
|
raise ValueError("number")
|
||||||
|
if 0 <= number < 16:
|
||||||
|
return str(number)
|
||||||
if 0 <= number < 0x100:
|
if 0 <= number < 0x100:
|
||||||
return "${:02x}".format(number)
|
return "${:02x}".format(number)
|
||||||
if 0 <= number < 0x10000:
|
if 0 <= number < 0x10000:
|
||||||
|
@ -270,6 +270,19 @@ class AssemblyGenerator:
|
|||||||
self.p("_init_strings_size = * - _init_strings_start")
|
self.p("_init_strings_size = * - _init_strings_start")
|
||||||
self.p("")
|
self.p("")
|
||||||
|
|
||||||
|
def _numeric_value_str(self, value: Any, as_hex: bool=False) -> str:
|
||||||
|
if isinstance(value, bool):
|
||||||
|
return "1" if value else "0"
|
||||||
|
if isinstance(value, int):
|
||||||
|
if as_hex:
|
||||||
|
return to_hex(value)
|
||||||
|
return str(value)
|
||||||
|
if isinstance(value, (int, float)):
|
||||||
|
if as_hex:
|
||||||
|
raise TypeError("cannot output float as hex")
|
||||||
|
return str(value)
|
||||||
|
raise TypeError("no numeric representation possible", value)
|
||||||
|
|
||||||
def generate_block_vars(self, block: Block, zeropage: bool=False) -> None:
|
def generate_block_vars(self, block: Block, zeropage: bool=False) -> None:
|
||||||
# Generate the block variable storage.
|
# Generate the block variable storage.
|
||||||
# The memory bytes of the allocated variables is set to zero (so it compresses very well),
|
# The memory bytes of the allocated variables is set to zero (so it compresses very well),
|
||||||
@ -280,9 +293,9 @@ class AssemblyGenerator:
|
|||||||
self.p("; constants")
|
self.p("; constants")
|
||||||
for vardef in vars_by_vartype.get(VarType.CONST, []):
|
for vardef in vars_by_vartype.get(VarType.CONST, []):
|
||||||
if vardef.datatype == DataType.FLOAT:
|
if vardef.datatype == DataType.FLOAT:
|
||||||
self.p("\v{:s} = {}".format(vardef.name, vardef.value))
|
self.p("\v{:s} = {}".format(vardef.name, self._numeric_value_str(vardef.value)))
|
||||||
elif vardef.datatype in (DataType.BYTE, DataType.WORD):
|
elif vardef.datatype in (DataType.BYTE, DataType.WORD):
|
||||||
self.p("\v{:s} = {:s}".format(vardef.name, to_hex(vardef.value)))
|
self.p("\v{:s} = {:s}".format(vardef.name, self._numeric_value_str(vardef.value, True)))
|
||||||
elif vardef.datatype in STRING_DATATYPES:
|
elif vardef.datatype in STRING_DATATYPES:
|
||||||
# a const string is just a string variable in the generated assembly
|
# a const string is just a string variable in the generated assembly
|
||||||
self._generate_string_var(vardef)
|
self._generate_string_var(vardef)
|
||||||
|
@ -258,7 +258,6 @@ class CodeGenerator:
|
|||||||
self.p("\t.pend\n")
|
self.p("\t.pend\n")
|
||||||
|
|
||||||
def generate_block_vars(self, block: Block) -> None:
|
def generate_block_vars(self, block: Block) -> None:
|
||||||
# @todo block vars should be re-initialized when the program is run again, and not depend on statically prefilled data!
|
|
||||||
consts = [c for c in block.symbols.iter_constants()]
|
consts = [c for c in block.symbols.iter_constants()]
|
||||||
if consts:
|
if consts:
|
||||||
self.p("; constants")
|
self.p("; constants")
|
||||||
@ -928,7 +927,7 @@ class CodeGenerator:
|
|||||||
if isinstance(stmt.target, MemMappedValue):
|
if isinstance(stmt.target, MemMappedValue):
|
||||||
targetstr = stmt.target.name or Parser.to_hex(stmt.address)
|
targetstr = stmt.target.name or Parser.to_hex(stmt.address)
|
||||||
else:
|
else:
|
||||||
raise CodeError("call sub target should be mmapped")
|
raise CodeError("call sub target must be mmapped")
|
||||||
if stmt.is_goto:
|
if stmt.is_goto:
|
||||||
generate_param_assignments()
|
generate_param_assignments()
|
||||||
branch_emitter(targetstr, True, False)
|
branch_emitter(targetstr, True, False)
|
||||||
@ -1857,7 +1856,7 @@ class CodeGenerator:
|
|||||||
self.p("\t\tld{:s} #<{:s}".format(lv.register[0].lower(), rvalue.name))
|
self.p("\t\tld{:s} #<{:s}".format(lv.register[0].lower(), rvalue.name))
|
||||||
self.p("\t\tld{:s} #>{:s}".format(lv.register[1].lower(), rvalue.name))
|
self.p("\t\tld{:s} #>{:s}".format(lv.register[1].lower(), rvalue.name))
|
||||||
else:
|
else:
|
||||||
raise CodeError("cannot assign immediate string, it should be a string variable")
|
raise CodeError("cannot assign immediate string, it must be a string variable")
|
||||||
|
|
||||||
def generate_assign_string_to_memory(self, lv: MemMappedValue, rvalue: StringValue) -> None:
|
def generate_assign_string_to_memory(self, lv: MemMappedValue, rvalue: StringValue) -> None:
|
||||||
if lv.datatype != DataType.WORD:
|
if lv.datatype != DataType.WORD:
|
||||||
@ -1869,7 +1868,7 @@ class CodeGenerator:
|
|||||||
self.p("\t\tlda #>{:s}".format(rvalue.name))
|
self.p("\t\tlda #>{:s}".format(rvalue.name))
|
||||||
self.p("\t\tsta {}+1".format(assign_target))
|
self.p("\t\tsta {}+1".format(assign_target))
|
||||||
else:
|
else:
|
||||||
raise CodeError("cannot assign immediate string, it should be a string variable")
|
raise CodeError("cannot assign immediate string, it must be a string variable")
|
||||||
|
|
||||||
def footer(self) -> None:
|
def footer(self) -> None:
|
||||||
self.p("\n\n.end")
|
self.p("\n\n.end")
|
||||||
|
@ -202,7 +202,7 @@ class Parser:
|
|||||||
for sub in block.symbols.iter_subroutines(True):
|
for sub in block.symbols.iter_subroutines(True):
|
||||||
self._check_return_statement(sub.sub_block, "subroutine '{:s}'".format(sub.name))
|
self._check_return_statement(sub.sub_block, "subroutine '{:s}'".format(sub.name))
|
||||||
if not main_found:
|
if not main_found:
|
||||||
raise self.PError("a block 'main' should be defined and contain the program's entry point label 'start'")
|
raise self.PError("a block 'main' must be defined and contain the program's entry point label 'start'")
|
||||||
|
|
||||||
def _check_return_statement(self, block: Block, message: str) -> None:
|
def _check_return_statement(self, block: Block, message: str) -> None:
|
||||||
# find last statement that isn't a comment
|
# find last statement that isn't a comment
|
||||||
@ -560,7 +560,7 @@ class Parser:
|
|||||||
arg = block_args.pop(0)
|
arg = block_args.pop(0)
|
||||||
if arg.isidentifier():
|
if arg.isidentifier():
|
||||||
if arg.lower() == "zeropage" or arg in ("zp", "zP", "Zp"):
|
if arg.lower() == "zeropage" or arg in ("zp", "zP", "Zp"):
|
||||||
raise self.PError("zero page block should be named 'ZP'")
|
raise self.PError("zero page block must be named 'ZP'")
|
||||||
is_zp_block = arg == "ZP"
|
is_zp_block = arg == "ZP"
|
||||||
if arg in set(b.name for b in self.result.blocks):
|
if arg in set(b.name for b in self.result.blocks):
|
||||||
orig = [b for b in self.result.blocks if b.name == arg][0]
|
orig = [b for b in self.result.blocks if b.name == arg][0]
|
||||||
@ -980,7 +980,7 @@ class Parser:
|
|||||||
return CallStmt(self.sourceref, target, address=address, arguments=arguments,
|
return CallStmt(self.sourceref, target, address=address, arguments=arguments,
|
||||||
outputs=outputvars, preserve_regs=preserve_regs)
|
outputs=outputvars, preserve_regs=preserve_regs)
|
||||||
else:
|
else:
|
||||||
raise TypeError("target should be a Value", target)
|
raise TypeError("target must be a Value", target)
|
||||||
|
|
||||||
def parse_integer(self, text: str) -> int:
|
def parse_integer(self, text: str) -> int:
|
||||||
text = text.strip()
|
text = text.strip()
|
||||||
|
@ -848,7 +848,7 @@ class IntegerValue(Value):
|
|||||||
self.value = value
|
self.value = value
|
||||||
elif value is None:
|
elif value is None:
|
||||||
if not name:
|
if not name:
|
||||||
raise ValueError("when integer value is not given, the name symbol should be speicified")
|
raise ValueError("when integer value is not given, the name symbol must be specified")
|
||||||
super().__init__(datatype, sourceref, name, True)
|
super().__init__(datatype, sourceref, name, True)
|
||||||
self.value = None
|
self.value = None
|
||||||
else:
|
else:
|
||||||
|
@ -481,7 +481,7 @@ _loop lda #0
|
|||||||
sub scroll_left_full (alsocolors: SC) -> (A?, X?, Y?) {
|
sub scroll_left_full (alsocolors: SC) -> (A?, X?, Y?) {
|
||||||
; ---- scroll the whole screen 1 character to the left
|
; ---- scroll the whole screen 1 character to the left
|
||||||
; contents of the rightmost column are unchanged, you should clear/refill this yourself
|
; contents of the rightmost column are unchanged, you should clear/refill this yourself
|
||||||
; Carry flag determines if screen color data should be scrolled too
|
; Carry flag determines if screen color data must be scrolled too
|
||||||
%asm {
|
%asm {
|
||||||
bcs +
|
bcs +
|
||||||
jmp _scroll_screen
|
jmp _scroll_screen
|
||||||
@ -540,7 +540,7 @@ _scroll_screen
|
|||||||
sub scroll_right_full (alsocolors: SC) -> (A?, X?) {
|
sub scroll_right_full (alsocolors: SC) -> (A?, X?) {
|
||||||
; ---- scroll the whole screen 1 character to the right
|
; ---- scroll the whole screen 1 character to the right
|
||||||
; contents of the leftmost column are unchanged, you should clear/refill this yourself
|
; contents of the leftmost column are unchanged, you should clear/refill this yourself
|
||||||
; Carry flag determines if screen color data should be scrolled too
|
; Carry flag determines if screen color data must be scrolled too
|
||||||
%asm {
|
%asm {
|
||||||
bcs +
|
bcs +
|
||||||
jmp _scroll_screen
|
jmp _scroll_screen
|
||||||
@ -591,7 +591,7 @@ _scroll_screen
|
|||||||
sub scroll_up_full (alsocolors: SC) -> (A?, X?) {
|
sub scroll_up_full (alsocolors: SC) -> (A?, X?) {
|
||||||
; ---- scroll the whole screen 1 character up
|
; ---- scroll the whole screen 1 character up
|
||||||
; contents of the bottom row are unchanged, you should refill/clear this yourself
|
; contents of the bottom row are unchanged, you should refill/clear this yourself
|
||||||
; Carry flag determines if screen color data should be scrolled too
|
; Carry flag determines if screen color data must be scrolled too
|
||||||
%asm {
|
%asm {
|
||||||
bcs +
|
bcs +
|
||||||
jmp _scroll_screen
|
jmp _scroll_screen
|
||||||
@ -642,7 +642,7 @@ _scroll_screen
|
|||||||
sub scroll_down_full (alsocolors: SC) -> (A?, X?) {
|
sub scroll_down_full (alsocolors: SC) -> (A?, X?) {
|
||||||
; ---- scroll the whole screen 1 character down
|
; ---- scroll the whole screen 1 character down
|
||||||
; contents of the top row are unchanged, you should refill/clear this yourself
|
; contents of the top row are unchanged, you should refill/clear this yourself
|
||||||
; Carry flag determines if screen color data should be scrolled too
|
; Carry flag determines if screen color data must be scrolled too
|
||||||
%asm {
|
%asm {
|
||||||
bcs +
|
bcs +
|
||||||
jmp _scroll_screen
|
jmp _scroll_screen
|
||||||
|
@ -50,6 +50,8 @@ def main() -> None:
|
|||||||
mon_command_file = assembler.generate_breakpoint_list(program_filename)
|
mon_command_file = assembler.generate_breakpoint_list(program_filename)
|
||||||
duration_total = time.perf_counter() - start
|
duration_total = time.perf_counter() - start
|
||||||
print("Compile duration: {:.2f} seconds".format(duration_total))
|
print("Compile duration: {:.2f} seconds".format(duration_total))
|
||||||
|
size = os.path.getsize(program_filename)
|
||||||
|
print("Output size: {:d} bytes".format(size))
|
||||||
print_bold("Output file: " + program_filename)
|
print_bold("Output file: " + program_filename)
|
||||||
print()
|
print()
|
||||||
if args.startvice:
|
if args.startvice:
|
||||||
|
@ -181,7 +181,7 @@ class Scope(AstNode):
|
|||||||
self._populate_symboltable(newnode)
|
self._populate_symboltable(newnode)
|
||||||
|
|
||||||
|
|
||||||
def validate_address(obj: AstNode, attrib: attr.Attribute, value: Optional[int]):
|
def validate_address(obj: AstNode, attrib: attr.Attribute, value: Optional[int]) -> None:
|
||||||
if value is None:
|
if value is None:
|
||||||
return
|
return
|
||||||
if isinstance(obj, Block) and obj.name == "ZP":
|
if isinstance(obj, Block) and obj.name == "ZP":
|
||||||
@ -190,6 +190,27 @@ def validate_address(obj: AstNode, attrib: attr.Attribute, value: Optional[int])
|
|||||||
raise ParseError("invalid {:s} (must be from $0200 to $ffff)".format(attrib.name), obj.sourceref)
|
raise ParseError("invalid {:s} (must be from $0200 to $ffff)".format(attrib.name), obj.sourceref)
|
||||||
|
|
||||||
|
|
||||||
|
def dimensions_validator(obj: 'DatatypeNode', attrib: attr.Attribute, value: List[int]) -> None:
|
||||||
|
if not value:
|
||||||
|
return
|
||||||
|
dt = obj.to_enum()
|
||||||
|
if value and dt not in (DataType.MATRIX, DataType.WORDARRAY, DataType.BYTEARRAY):
|
||||||
|
raise ParseError("cannot use a dimension for this datatype", obj.sourceref)
|
||||||
|
if dt == DataType.WORDARRAY or dt == DataType.BYTEARRAY:
|
||||||
|
if len(value) == 1:
|
||||||
|
if value[0] <= 0 or value[0] > 256:
|
||||||
|
raise ParseError("array length must be 1..256", obj.sourceref)
|
||||||
|
else:
|
||||||
|
raise ParseError("array must have only one dimension", obj.sourceref)
|
||||||
|
if dt == DataType.MATRIX:
|
||||||
|
if len(value) == 2:
|
||||||
|
size = value[0] * value[1]
|
||||||
|
if size <= 0 or size > 0x8000:
|
||||||
|
raise ParseError("matrix size columns * rows must be 1..32768", obj.sourceref)
|
||||||
|
else:
|
||||||
|
raise ParseError("matrix must have two dimensions", obj.sourceref)
|
||||||
|
|
||||||
|
|
||||||
@attr.s(cmp=False, repr=False)
|
@attr.s(cmp=False, repr=False)
|
||||||
class Block(AstNode):
|
class Block(AstNode):
|
||||||
scope = attr.ib(type=Scope)
|
scope = attr.ib(type=Scope)
|
||||||
@ -432,7 +453,7 @@ class VarDef(AstNode):
|
|||||||
@attr.s(cmp=False, slots=True, repr=False)
|
@attr.s(cmp=False, slots=True, repr=False)
|
||||||
class DatatypeNode(AstNode):
|
class DatatypeNode(AstNode):
|
||||||
name = attr.ib(type=str)
|
name = attr.ib(type=str)
|
||||||
dimensions = attr.ib(type=list, default=None) # if set, 1 or more dimensions (ints)
|
dimensions = attr.ib(type=list, default=None, validator=dimensions_validator) # if set, 1 or more dimensions (ints)
|
||||||
|
|
||||||
def to_enum(self):
|
def to_enum(self):
|
||||||
return {
|
return {
|
||||||
@ -556,7 +577,7 @@ class Expression(AstNode):
|
|||||||
assert self.operator not in ("++", "--"), "incr/decr should not be an expression"
|
assert self.operator not in ("++", "--"), "incr/decr should not be an expression"
|
||||||
|
|
||||||
def process_expressions(self, scope: Scope) -> None:
|
def process_expressions(self, scope: Scope) -> None:
|
||||||
raise RuntimeError("should be done via parent node's process_expressions")
|
raise RuntimeError("must be done via parent node's process_expressions")
|
||||||
|
|
||||||
def evaluate_primitive_constants(self, scope: Scope) -> Union[int, float, str, bool]:
|
def evaluate_primitive_constants(self, scope: Scope) -> Union[int, float, str, bool]:
|
||||||
# make sure the lvalue and rvalue are primitives, and the operator is allowed
|
# make sure the lvalue and rvalue are primitives, and the operator is allowed
|
||||||
@ -628,9 +649,11 @@ def process_constant_expression(expr: Any, sourceref: SourceRef, symbolscope: Sc
|
|||||||
return value.value
|
return value.value
|
||||||
if value.vartype == VarType.CONST:
|
if value.vartype == VarType.CONST:
|
||||||
raise ExpressionEvaluationError("can't take the address of a constant", expr.name.sourceref)
|
raise ExpressionEvaluationError("can't take the address of a constant", expr.name.sourceref)
|
||||||
raise ExpressionEvaluationError("address-of this {} isn't a compile-time constant".format(value.__class__.__name__), expr.name.sourceref)
|
raise ExpressionEvaluationError("address-of this {} isn't a compile-time 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):
|
||||||
@ -656,9 +679,9 @@ def process_constant_expression(expr: Any, sourceref: SourceRef, symbolscope: Sc
|
|||||||
else:
|
else:
|
||||||
raise ExpressionEvaluationError("can only use math- or builtin function", expr.sourceref)
|
raise ExpressionEvaluationError("can only use math- or builtin function", expr.sourceref)
|
||||||
elif isinstance(target, Dereference): # '[...](1,2,3)'
|
elif isinstance(target, Dereference): # '[...](1,2,3)'
|
||||||
return None # XXX
|
return None # XXX
|
||||||
elif isinstance(target, int): # '64738()'
|
elif isinstance(target, int): # '64738()'
|
||||||
return None # XXX
|
return None # XXX
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError("weird call target", target) # XXX
|
raise NotImplementedError("weird call target", target) # XXX
|
||||||
else:
|
else:
|
||||||
|
@ -22,8 +22,11 @@ def test_parseerror():
|
|||||||
|
|
||||||
|
|
||||||
def test_to_hex():
|
def test_to_hex():
|
||||||
assert datatypes.to_hex(0) == "$00"
|
assert datatypes.to_hex(0) == "0"
|
||||||
assert datatypes.to_hex(1) == "$01"
|
assert datatypes.to_hex(1) == "1"
|
||||||
|
assert datatypes.to_hex(10) == "10"
|
||||||
|
assert datatypes.to_hex(15) == "15"
|
||||||
|
assert datatypes.to_hex(16) == "$10"
|
||||||
assert datatypes.to_hex(255) == "$ff"
|
assert datatypes.to_hex(255) == "$ff"
|
||||||
assert datatypes.to_hex(256) == "$0100"
|
assert datatypes.to_hex(256) == "$0100"
|
||||||
assert datatypes.to_hex(20060) == "$4e5c"
|
assert datatypes.to_hex(20060) == "$4e5c"
|
||||||
|
@ -65,10 +65,10 @@
|
|||||||
var .float initfloat5 = -1.70141183e+38
|
var .float initfloat5 = -1.70141183e+38
|
||||||
var .float initfloat6 = 1.234
|
var .float initfloat6 = 1.234
|
||||||
|
|
||||||
var .wordarray( 10 ) uninit_wordarray
|
var .wordarray( 256 ) uninit_wordarray
|
||||||
var .wordarray(10) init_wordarray = $1234
|
var .wordarray(10) init_wordarray = $1234
|
||||||
var .wordarray(10) init_wordarrayb = true
|
var .wordarray(10) init_wordarrayb = true
|
||||||
var .array( 10) uninit_bytearray
|
var .array( 256) 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 ='@'
|
||||||
@ -78,7 +78,7 @@
|
|||||||
var .stext stext = 'screencodes-null'
|
var .stext stext = 'screencodes-null'
|
||||||
var .pstext pstext = "screencodes-pascal"
|
var .pstext pstext = "screencodes-pascal"
|
||||||
|
|
||||||
var .matrix( 10, 20 ) uninitmatrix
|
var .matrix( 2, 400 ) uninitmatrix
|
||||||
var .matrix(10, 20) initmatrix1 = $12
|
var .matrix(10, 20) initmatrix1 = $12
|
||||||
var .matrix(10, 20) initmatrix1b = true
|
var .matrix(10, 20) initmatrix1b = true
|
||||||
var .matrix(10, 20) initmatrix1c = '@'
|
var .matrix(10, 20) initmatrix1c = '@'
|
||||||
|
Loading…
Reference in New Issue
Block a user