mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
vm: printing of numbers now via conv module.
assigning strings now converted to strcopy function call in the compiler ast.
This commit is contained in:
parent
7eea97d741
commit
cf50e4f6ec
@ -185,15 +185,7 @@ internal class AssignmentAsmGen(private val program: Program,
|
||||
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||
}
|
||||
DataType.STR, DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||
// copy the actual string result into the target string variable
|
||||
asmgen.out("""
|
||||
pha
|
||||
lda #<${assign.target.asmVarname}
|
||||
sta P8ZP_SCRATCH_W1
|
||||
lda #>${assign.target.asmVarname}
|
||||
sta P8ZP_SCRATCH_W1+1
|
||||
pla
|
||||
jsr prog8_lib.strcpy""")
|
||||
throw AssemblyError("stringvalue assignment should have been replaced by a call to strcpy")
|
||||
}
|
||||
else -> throw AssemblyError("weird target dt")
|
||||
}
|
||||
|
@ -568,6 +568,7 @@ class CodeGen(internal val program: PtProgram,
|
||||
|
||||
private fun translate(assignment: PtAssignment): VmCodeChunk {
|
||||
// TODO can in-place assignments be optimized more?
|
||||
// note: assigning array and string values is done via an explicit memcopy/stringcopy function call.
|
||||
if(assignment.target.children.single() is PtMachineRegister)
|
||||
throw AssemblyError("assigning to a register should be done by just evaluating the expression into resultregister")
|
||||
val code = VmCodeChunk()
|
||||
@ -607,7 +608,7 @@ class CodeGen(internal val program: PtProgram,
|
||||
code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1=resultRegister, value=(memory.address as PtNumber).number.toInt())
|
||||
} else {
|
||||
val addressReg = vmRegisters.nextFree()
|
||||
code += expressionEval.translateExpression(assignment.value, addressReg)
|
||||
code += expressionEval.translateExpression(memory.address, addressReg)
|
||||
code += VmCodeInstruction(Opcode.STOREI, vmDt, reg1=resultRegister, reg2=addressReg)
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,17 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub internal_stringcopy(uword source @R0, uword target @AY) clobbers (A,Y) {
|
||||
; Called when the compiler wants to assign a string value to another string.
|
||||
%asm {{
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda cx16.r0
|
||||
ldy cx16.r0+1
|
||||
jmp prog8_lib.strcpy
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub memcopy(uword source @R0, uword target @R1, uword count @AY) clobbers(A,X,Y) {
|
||||
; note: only works for NON-OVERLAPPING memory regions!
|
||||
; note: can't be inlined because is called from asm as well
|
||||
|
@ -554,6 +554,17 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub internal_stringcopy(uword source @R0, uword target @AY) clobbers (A,Y) {
|
||||
; Called when the compiler wants to assign a string value to another string.
|
||||
%asm {{
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda cx16.r0
|
||||
ldy cx16.r0+1
|
||||
jmp prog8_lib.strcpy
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub memcopy(uword source @R0, uword target @R1, uword count @AY) clobbers(A,X,Y) {
|
||||
; note: only works for NON-OVERLAPPING memory regions!
|
||||
; note: can't be inlined because is called from asm as well
|
||||
|
@ -519,6 +519,17 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub internal_stringcopy(uword source @R0, uword target @AY) clobbers (A,Y) {
|
||||
; Called when the compiler wants to assign a string value to another string.
|
||||
%asm {{
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda cx16.r0
|
||||
ldy cx16.r0+1
|
||||
jmp prog8_lib.strcpy
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub memcopy(uword source @R0, uword target @R1, uword count @AY) clobbers(A,X,Y) {
|
||||
; note: only works for NON-OVERLAPPING memory regions!
|
||||
; note: can't be inlined because is called from asm as well
|
||||
|
@ -267,7 +267,7 @@ inline asmsub str2ubyte(str string @AY) clobbers(Y) -> ubyte @A {
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub str2byte(str string @AY) clobbers(Y) -> ubyte @A {
|
||||
inline asmsub str2byte(str string @AY) clobbers(Y) -> byte @A {
|
||||
; -- returns in A the signed byte value of the string number argument in AY
|
||||
; the number may be preceded by a + or - sign but may NOT contain spaces
|
||||
; (any non-digit character will terminate the number string that is parsed)
|
||||
|
@ -840,6 +840,17 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub internal_stringcopy(uword source @R0, uword target @AY) clobbers (A,Y) {
|
||||
; Called when the compiler wants to assign a string value to another string.
|
||||
%asm {{
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda cx16.r0
|
||||
ldy cx16.r0+1
|
||||
jmp prog8_lib.strcpy
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub memcopy(uword source @R0, uword target @R1, uword count @AY) clobbers(A,X,Y) {
|
||||
; note: only works for NON-OVERLAPPING memory regions!
|
||||
; If you have to copy overlapping memory regions, consider using
|
||||
|
230
compiler/res/prog8lib/virtual/conv.p8
Normal file
230
compiler/res/prog8lib/virtual/conv.p8
Normal file
@ -0,0 +1,230 @@
|
||||
; Number conversions routines.
|
||||
;
|
||||
; Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
||||
|
||||
|
||||
conv {
|
||||
|
||||
; ----- number conversions to decimal strings ----
|
||||
|
||||
str string_out = "????????????????" ; result buffer for the string conversion routines
|
||||
|
||||
sub str_ub0(ubyte value) {
|
||||
; ---- convert the ubyte in A in decimal string form, with left padding 0s (3 positions total)
|
||||
ubyte hundreds = value / 100
|
||||
value -= hundreds*100
|
||||
ubyte tens = value / 10
|
||||
value -= tens*10
|
||||
string_out[0] = hundreds+'0'
|
||||
string_out[1] = tens+'0'
|
||||
string_out[2] = value+'0'
|
||||
string_out[3] = 0
|
||||
}
|
||||
|
||||
sub str_ub(ubyte value) {
|
||||
; ---- convert the ubyte in A in decimal string form, without left padding 0s
|
||||
internal_str_ub(value, string_out)
|
||||
}
|
||||
|
||||
sub str_b(byte value) {
|
||||
; ---- convert the byte in A in decimal string form, without left padding 0s
|
||||
uword out_ptr = &string_out
|
||||
if value<0 {
|
||||
@(out_ptr) = '-'
|
||||
out_ptr++
|
||||
value = -value
|
||||
}
|
||||
internal_str_ub(value as ubyte, out_ptr)
|
||||
}
|
||||
|
||||
sub internal_str_ub(ubyte value, uword out_ptr) {
|
||||
ubyte hundreds = value / 100
|
||||
value -= hundreds*100
|
||||
ubyte tens = value / 10
|
||||
value -= tens*10
|
||||
if hundreds
|
||||
goto output_hundreds
|
||||
if tens
|
||||
goto output_tens
|
||||
goto output_ones
|
||||
output_hundreds:
|
||||
@(out_ptr) = hundreds+'0'
|
||||
out_ptr++
|
||||
output_tens:
|
||||
@(out_ptr) = tens+'0'
|
||||
out_ptr++
|
||||
output_ones:
|
||||
@(out_ptr) = value+'0'
|
||||
out_ptr++
|
||||
@(out_ptr) = 0
|
||||
}
|
||||
|
||||
str hex_digits = "0123456789abcdef"
|
||||
|
||||
sub str_ubhex (ubyte value) {
|
||||
; ---- convert the ubyte in A in hex string form
|
||||
string_out[0] = hex_digits[value>>4]
|
||||
string_out[1] = hex_digits[value&15]
|
||||
string_out[2] = 0
|
||||
}
|
||||
|
||||
sub str_ubbin (ubyte value) {
|
||||
; ---- convert the ubyte in A in binary string form
|
||||
uword out_ptr = &string_out
|
||||
repeat 8 {
|
||||
rol(value)
|
||||
if_cc
|
||||
@(out_ptr) = '0'
|
||||
else
|
||||
@(out_ptr) = '1'
|
||||
out_ptr++
|
||||
}
|
||||
@(out_ptr) = 0
|
||||
}
|
||||
|
||||
sub str_uwbin (uword value) {
|
||||
; ---- convert the uword in A/Y in binary string form
|
||||
uword out_ptr = &string_out
|
||||
repeat 16 {
|
||||
rol(value)
|
||||
if_cc
|
||||
@(out_ptr) = '0'
|
||||
else
|
||||
@(out_ptr) = '1'
|
||||
out_ptr++
|
||||
}
|
||||
@(out_ptr) = 0
|
||||
}
|
||||
|
||||
sub str_uwhex (uword value) {
|
||||
; ---- convert the uword in A/Y in hexadecimal string form (4 digits)
|
||||
ubyte bits = msb(value)
|
||||
string_out[0] = hex_digits[bits>>4]
|
||||
string_out[1] = hex_digits[bits&15]
|
||||
bits = lsb(value)
|
||||
string_out[2] = hex_digits[bits>>4]
|
||||
string_out[3] = hex_digits[bits&15]
|
||||
string_out[4] = 0
|
||||
}
|
||||
|
||||
sub str_uw0 (uword value) {
|
||||
; ---- convert the uword in A/Y in decimal string form, with left padding 0s (5 positions total)
|
||||
ubyte tenthousands = (value / 10000) as ubyte
|
||||
value -= 10000*tenthousands
|
||||
ubyte thousands = (value / 1000) as ubyte
|
||||
value -= 1000*thousands
|
||||
ubyte hundreds = (value / 100) as ubyte
|
||||
value -= 100 as uword * hundreds
|
||||
ubyte tens = (value / 10) as ubyte
|
||||
value -= 10*tens
|
||||
string_out[0] = tenthousands+'0'
|
||||
string_out[1] = thousands+'0'
|
||||
string_out[2] = hundreds+'0'
|
||||
string_out[3] = tens+'0'
|
||||
string_out[4] = value as ubyte + '0'
|
||||
string_out[5] = 0
|
||||
}
|
||||
|
||||
sub str_uw (uword value) {
|
||||
; ---- convert the uword in A/Y in decimal string form, without left padding 0s
|
||||
internal_str_uw(value, string_out)
|
||||
}
|
||||
|
||||
sub str_w (word value) {
|
||||
; ---- convert the (signed) word in A/Y in decimal string form, without left padding 0's
|
||||
uword out_ptr = &string_out
|
||||
if value<0 {
|
||||
@(out_ptr) = '-'
|
||||
out_ptr++
|
||||
value = -value
|
||||
}
|
||||
internal_str_uw(value as uword, out_ptr)
|
||||
}
|
||||
|
||||
sub internal_str_uw(uword value, uword out_ptr) {
|
||||
ubyte tenthousands = (value / 10000) as ubyte
|
||||
value -= 10000*tenthousands
|
||||
ubyte thousands = (value / 1000) as ubyte
|
||||
value -= 1000*thousands
|
||||
ubyte hundreds = (value / 100) as ubyte
|
||||
value -= 100 as uword * hundreds
|
||||
ubyte tens = (value / 10) as ubyte
|
||||
value -= 10*tens
|
||||
if tenthousands
|
||||
goto output_tenthousands
|
||||
if thousands
|
||||
goto output_thousands
|
||||
if hundreds
|
||||
goto output_hundreds
|
||||
if tens
|
||||
goto output_tens
|
||||
goto output_ones
|
||||
output_tenthousands:
|
||||
@(out_ptr) = tenthousands+'0'
|
||||
out_ptr++
|
||||
output_thousands:
|
||||
@(out_ptr) = thousands+'0'
|
||||
out_ptr++
|
||||
output_hundreds:
|
||||
@(out_ptr) = hundreds+'0'
|
||||
out_ptr++
|
||||
output_tens:
|
||||
@(out_ptr) = tens+'0'
|
||||
out_ptr++
|
||||
output_ones:
|
||||
@(out_ptr) = value as ubyte + '0'
|
||||
out_ptr++
|
||||
@(out_ptr) = 0
|
||||
}
|
||||
|
||||
|
||||
; ---- string conversion to numbers -----
|
||||
|
||||
sub str2ubyte(str string) -> ubyte {
|
||||
; -- returns in A the unsigned byte value of the string number argument in AY
|
||||
; the number may NOT be preceded by a + sign and may NOT contain spaces
|
||||
; (any non-digit character will terminate the number string that is parsed)
|
||||
; TODO
|
||||
return 0
|
||||
}
|
||||
|
||||
sub str2byte(str string) -> byte {
|
||||
; -- returns in A the signed byte value of the string number argument in AY
|
||||
; the number may be preceded by a + or - sign but may NOT contain spaces
|
||||
; (any non-digit character will terminate the number string that is parsed)
|
||||
; TODO
|
||||
return 0
|
||||
}
|
||||
|
||||
sub str2uword(str string) -> uword {
|
||||
; -- returns the unsigned word value of the string number argument in AY
|
||||
; the number may NOT be preceded by a + sign and may NOT contain spaces
|
||||
; (any non-digit character will terminate the number string that is parsed)
|
||||
; TODO
|
||||
return 0
|
||||
}
|
||||
|
||||
sub str2word(str string) -> word {
|
||||
; -- returns the signed word value of the string number argument in AY
|
||||
; the number may be preceded by a + or - sign but may NOT contain spaces
|
||||
; (any non-digit character will terminate the number string that is parsed)
|
||||
; TODO
|
||||
return 0
|
||||
}
|
||||
|
||||
sub hex2uword(str string) -> uword {
|
||||
; -- hexadecimal string (with or without '$') to uword.
|
||||
; string may be in petscii or c64-screencode encoding.
|
||||
; stops parsing at the first character that's not a hex digit (except leading $)
|
||||
; TODO
|
||||
return 0
|
||||
}
|
||||
|
||||
sub bin2uword(str string) -> uword {
|
||||
; -- binary string (with or without '%') to uword.
|
||||
; stops parsing at the first character that's not a 0 or 1. (except leading %)
|
||||
; TODO
|
||||
return 0
|
||||
}
|
||||
|
||||
}
|
94
compiler/res/prog8lib/virtual/floats.p8
Normal file
94
compiler/res/prog8lib/virtual/floats.p8
Normal file
@ -0,0 +1,94 @@
|
||||
; Prog8 definitions for floating point handling on the VirtualMachine
|
||||
;
|
||||
; Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
||||
|
||||
%option enable_floats
|
||||
|
||||
floats {
|
||||
|
||||
const float PI = 3.141592653589793
|
||||
const float TWOPI = 6.283185307179586
|
||||
|
||||
sub print_f(float value) {
|
||||
; ---- prints the floating point value (without a newline).
|
||||
; TODO
|
||||
}
|
||||
|
||||
sub pow(float value, float power) -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub fabs(float value) -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub sin(float angle) -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub cos(float angle) -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub tan(float value) -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub atan(float value) -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub ln(float value) -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub log2(float value) -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub sqrt(float value) -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub rad(float angle) -> float {
|
||||
; -- convert degrees to radians (d * pi / 180)
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub deg(float angle) -> float {
|
||||
; -- convert radians to degrees (d * (1/ pi * 180))
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub round(float value) -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub floor(float value) -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub ceil(float value) -> float {
|
||||
; -- ceil: tr = int(f); if tr==f -> return else return tr+1
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
|
||||
sub rndf() -> float {
|
||||
; TODO
|
||||
return 0.0
|
||||
}
|
||||
}
|
@ -81,6 +81,16 @@ sys {
|
||||
void syscall(SC_WAITVSYNC)
|
||||
}
|
||||
|
||||
sub internal_stringcopy(uword source, uword target) {
|
||||
; Called when the compiler wants to assign a string value to another string.
|
||||
while @(source) {
|
||||
@(target) = @(source)
|
||||
source++
|
||||
target++
|
||||
}
|
||||
@(target)=0
|
||||
}
|
||||
|
||||
sub memcopy(uword source, uword target, uword count) {
|
||||
repeat count {
|
||||
@(target) = @(source)
|
||||
|
@ -2,8 +2,7 @@
|
||||
;
|
||||
; Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
||||
|
||||
%import syslib
|
||||
|
||||
%import conv
|
||||
|
||||
txt {
|
||||
|
||||
@ -37,146 +36,70 @@ sub print (str text) {
|
||||
|
||||
sub print_ub0 (ubyte value) {
|
||||
; ---- print the ubyte in A in decimal form, with left padding 0s (3 positions total)
|
||||
; TODO use conv module?
|
||||
ubyte hundreds = value / 100
|
||||
value -= hundreds*100
|
||||
ubyte tens = value / 10
|
||||
value -= tens*10
|
||||
chrout(hundreds+'0')
|
||||
chrout(tens+'0')
|
||||
chrout(value+'0')
|
||||
conv.str_ub0(value)
|
||||
print(conv.string_out)
|
||||
}
|
||||
|
||||
sub print_ub (ubyte value) {
|
||||
; ---- print the ubyte in decimal form, without left padding 0s
|
||||
; TODO use conv module?
|
||||
ubyte hundreds = value / 100
|
||||
value -= hundreds*100
|
||||
ubyte tens = value / 10
|
||||
value -= tens*10
|
||||
if hundreds
|
||||
goto print_hundreds
|
||||
if tens
|
||||
goto print_tens
|
||||
goto print_ones
|
||||
print_hundreds:
|
||||
chrout(hundreds+'0')
|
||||
print_tens:
|
||||
chrout(tens+'0')
|
||||
print_ones:
|
||||
chrout(value+'0')
|
||||
conv.str_ub(value)
|
||||
print(conv.string_out)
|
||||
}
|
||||
|
||||
sub print_b (byte value) {
|
||||
; ---- print the byte in decimal form, without left padding 0s
|
||||
if value<0 {
|
||||
chrout('-')
|
||||
value = -value
|
||||
}
|
||||
print_ub(value as ubyte)
|
||||
conv.str_b(value)
|
||||
print(conv.string_out)
|
||||
}
|
||||
|
||||
str hex_digits = "0123456789abcdef"
|
||||
|
||||
sub print_ubhex (ubyte value, ubyte prefix) {
|
||||
; ---- print the ubyte in hex form
|
||||
if prefix
|
||||
chrout('$')
|
||||
|
||||
chrout(hex_digits[value>>4])
|
||||
chrout(hex_digits[value&15])
|
||||
conv.str_ubhex(value)
|
||||
print(conv.string_out)
|
||||
}
|
||||
|
||||
sub print_ubbin (ubyte value, ubyte prefix) {
|
||||
; ---- print the ubyte in binary form
|
||||
; TODO use conv module?
|
||||
if prefix
|
||||
chrout('%')
|
||||
repeat 8 {
|
||||
rol(value)
|
||||
if_cc
|
||||
txt.chrout('0')
|
||||
else
|
||||
txt.chrout('1')
|
||||
}
|
||||
conv.str_ubbin(value)
|
||||
print(conv.string_out)
|
||||
}
|
||||
|
||||
sub print_uwbin (uword value, ubyte prefix) {
|
||||
; ---- print the uword in binary form
|
||||
; TODO use conv module?
|
||||
if prefix
|
||||
chrout('%')
|
||||
repeat 16 {
|
||||
rol(value)
|
||||
if_cc
|
||||
txt.chrout('0')
|
||||
else
|
||||
txt.chrout('1')
|
||||
}
|
||||
conv.str_uwbin(value)
|
||||
print(conv.string_out)
|
||||
}
|
||||
|
||||
sub print_uwhex (uword value, ubyte prefix) {
|
||||
; ---- print the uword in hexadecimal form (4 digits)
|
||||
print_ubhex(msb(value), true)
|
||||
print_ubhex(lsb(value), false)
|
||||
if prefix
|
||||
chrout('$')
|
||||
conv.str_uwhex(value)
|
||||
print(conv.string_out)
|
||||
}
|
||||
|
||||
sub print_uw0 (uword value) {
|
||||
; ---- print the uword value in decimal form, with left padding 0s (5 positions total)
|
||||
; TODO use conv module?
|
||||
ubyte tenthousands = (value / 10000) as ubyte
|
||||
value -= 10000*tenthousands
|
||||
ubyte thousands = (value / 1000) as ubyte
|
||||
value -= 1000*thousands
|
||||
ubyte hundreds = (value / 100) as ubyte
|
||||
value -= 100 as uword * hundreds
|
||||
ubyte tens = (value / 10) as ubyte
|
||||
value -= 10*tens
|
||||
chrout(tenthousands+'0')
|
||||
chrout(thousands+'0')
|
||||
chrout(hundreds+'0')
|
||||
chrout(tens+'0')
|
||||
chrout(value as ubyte + '0')
|
||||
conv.str_uw0(value)
|
||||
print(conv.string_out)
|
||||
}
|
||||
|
||||
sub print_uw (uword value) {
|
||||
; ---- print the uword in decimal form, without left padding 0s
|
||||
ubyte tenthousands = (value / 10000) as ubyte
|
||||
value -= 10000*tenthousands
|
||||
ubyte thousands = (value / 1000) as ubyte
|
||||
value -= 1000*thousands
|
||||
ubyte hundreds = (value / 100) as ubyte
|
||||
value -= 100 as uword * hundreds
|
||||
ubyte tens = (value / 10) as ubyte
|
||||
value -= 10*tens
|
||||
if tenthousands
|
||||
goto print_tenthousands
|
||||
if thousands
|
||||
goto print_thousands
|
||||
if hundreds
|
||||
goto print_hundreds
|
||||
if tens
|
||||
goto print_tens
|
||||
goto print_ones
|
||||
print_tenthousands:
|
||||
chrout(tenthousands+'0')
|
||||
print_thousands:
|
||||
chrout(thousands+'0')
|
||||
print_hundreds:
|
||||
chrout(hundreds+'0')
|
||||
print_tens:
|
||||
chrout(tens+'0')
|
||||
print_ones:
|
||||
chrout(value as ubyte + '0')
|
||||
conv.str_uw(value)
|
||||
print(conv.string_out)
|
||||
}
|
||||
|
||||
sub print_w (word value) {
|
||||
; ---- print the (signed) word in decimal form, without left padding 0's
|
||||
if value<0 {
|
||||
chrout('-')
|
||||
value = -value
|
||||
}
|
||||
print_uw(value as uword)
|
||||
conv.str_w(value)
|
||||
print(conv.string_out)
|
||||
}
|
||||
|
||||
sub input_chars (uword buffer) -> ubyte {
|
||||
|
@ -316,6 +316,9 @@ internal class StatementReorderer(val program: Program,
|
||||
}
|
||||
}
|
||||
|
||||
if(valueType.isString && (targetType istype DataType.STR || targetType istype DataType.ARRAY_B || targetType istype DataType.ARRAY_UB))
|
||||
return copyStringValue(assignment)
|
||||
|
||||
return noModifications
|
||||
}
|
||||
|
||||
@ -409,8 +412,26 @@ internal class StatementReorderer(val program: Program,
|
||||
return listOf(IAstModification.ReplaceNode(assign, memcopy, assign.parent))
|
||||
}
|
||||
|
||||
private fun copyStringValue(assign: Assignment): List<IAstModification> {
|
||||
val identifier = assign.target.identifier!!
|
||||
val sourceIdent = assign.value as? IdentifierReference
|
||||
val strcopy = FunctionCallStatement(IdentifierReference(listOf("sys", "internal_stringcopy"), assign.position),
|
||||
mutableListOf(
|
||||
if(sourceIdent!=null)
|
||||
AddressOf(sourceIdent, assign.position)
|
||||
else
|
||||
assign.value,
|
||||
AddressOf(identifier, assign.position)
|
||||
),
|
||||
true,
|
||||
assign.position
|
||||
)
|
||||
return listOf(IAstModification.ReplaceNode(assign, strcopy, assign.parent))
|
||||
}
|
||||
|
||||
override fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
|
||||
val function = functionCallStatement.target.targetStatement(program)!!
|
||||
val function = functionCallStatement.target.targetStatement(program)
|
||||
?: throw FatalAstException("no target for $functionCallStatement")
|
||||
checkUnusedReturnValues(functionCallStatement, function, program, errors)
|
||||
return tryReplaceCallWithGosub(functionCallStatement, parent, program, options)
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- %import inside a block/subroutine should give compilation error
|
||||
- pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls.
|
||||
- createAssemblyAndAssemble(): make it possible to actually get rid of the VarDecl nodes by fixing the rest of the code mentioned there.
|
||||
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type
|
||||
|
@ -1,40 +1,72 @@
|
||||
%import textio
|
||||
%import floats
|
||||
; %import floats
|
||||
%import conv
|
||||
%zeropage dontuse
|
||||
|
||||
|
||||
; NOTE: meant to test to virtual machine output target (use -target vitual)
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
sub newstring() -> str {
|
||||
return "new"
|
||||
}
|
||||
|
||||
float f1 = 1.555
|
||||
floats.print_f(floats.sin(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.cos(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.tan(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.atan(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.ln(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.log2(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.sqrt(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.rad(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.deg(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.round(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.floor(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.ceil(f1))
|
||||
txt.nl()
|
||||
floats.print_f(floats.rndf())
|
||||
txt.nl()
|
||||
sub start() {
|
||||
str name = "irmen\n"
|
||||
txt.print(name)
|
||||
name = "pipo\n"
|
||||
txt.print(name)
|
||||
|
||||
ubyte cc
|
||||
ubyte[] array = [11,22,33,44]
|
||||
for cc in array {
|
||||
txt.print_ub(cc)
|
||||
txt.spc()
|
||||
}
|
||||
txt.nl()
|
||||
array = [99,88,77,66]
|
||||
for cc in array {
|
||||
txt.print_ub(cc)
|
||||
txt.spc()
|
||||
}
|
||||
txt.nl()
|
||||
|
||||
txt.print_ub0(99)
|
||||
txt.spc()
|
||||
txt.print_ub(99)
|
||||
txt.nl()
|
||||
txt.print_uw0(9988)
|
||||
txt.spc()
|
||||
txt.print_uw(9988)
|
||||
txt.nl()
|
||||
|
||||
; float f1 = 1.555
|
||||
; floats.print_f(floats.sin(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.cos(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.tan(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.atan(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.ln(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.log2(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.sqrt(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.rad(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.deg(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.round(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.floor(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.ceil(f1))
|
||||
; txt.nl()
|
||||
; floats.print_f(floats.rndf())
|
||||
; txt.nl()
|
||||
; "sin", "cos", "tan", "atan",
|
||||
; "ln", "log2", "sqrt", "rad",
|
||||
; "deg", "round", "floor", "ceil", "rndf"
|
||||
|
Loading…
Reference in New Issue
Block a user