mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
removed string conversion builtin functions, they're now subroutines in c64util
This commit is contained in:
parent
6a18c83fa5
commit
d55bbcf706
@ -23,7 +23,7 @@
|
||||
|
||||
; use loop to write characters
|
||||
str bye = "Goodbye!\n"
|
||||
for ubyte c in 0 to len(bye) { ; @TODO fix compiler crash
|
||||
for ubyte c in 0 to len(bye) { ; @TODO fix compiler crash. Parent of assignment to c should be the anonymous scope 'c' is in, instead of the for loop itself.
|
||||
c64.CHROUT(bye[c])
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
c64scr.print("es")
|
||||
c64scr.print(" left.\nWhat is your next guess? ")
|
||||
c64scr.input_chars(input)
|
||||
ubyte guess = str2ubyte(input)
|
||||
ubyte guess = c64utils.str2ubyte(input)
|
||||
|
||||
; debug info
|
||||
; c64scr.print(" > attempts left=")
|
||||
|
@ -21,7 +21,7 @@
|
||||
vm_write_str("es")
|
||||
vm_write_str(" left. What is your next guess? ")
|
||||
vm_input_str(input)
|
||||
ubyte guess = str2ubyte(input)
|
||||
ubyte guess = c64utils.str2ubyte(input) ; @todo replace with proper stubs for these functions when executing on stackvm.
|
||||
if guess==secretnumber {
|
||||
vm_write_str("\nYou guessed it, impressive!\n")
|
||||
vm_write_str("Thanks for playing.\n")
|
||||
|
@ -28,9 +28,9 @@
|
||||
}
|
||||
|
||||
sub screenx(float x) -> ubyte {
|
||||
return b2ub(fintb(x * flt(width)/2.2) + width//2)
|
||||
return (x * width/2.2) + width//2 as ubyte
|
||||
}
|
||||
sub screeny(float y) -> ubyte {
|
||||
return b2ub(fintb(y * flt(height)/2.2) + height//2)
|
||||
return (y * height/2.2) + height//2 as ubyte
|
||||
}
|
||||
}
|
||||
|
@ -23,9 +23,13 @@
|
||||
}
|
||||
|
||||
sub screenx(float x) -> word {
|
||||
return fintw(x * flt(width)/4.1) + width // 2
|
||||
; return (x/4.1* (width as float) as word) + width // 2 ; @todo fix calculation
|
||||
float wf = width
|
||||
return (x/4.1* wf + wf / 2) as word
|
||||
}
|
||||
sub screeny(float y) -> word {
|
||||
return fintw(y * flt(height)/4.1) + height // 2
|
||||
;return (y/4.1 * (height as float) as word) + height // 2 ; @todo fix calculation
|
||||
float hf = height
|
||||
return (y/4.1 * hf + hf/ 2) as word
|
||||
}
|
||||
}
|
||||
|
@ -1,111 +1,86 @@
|
||||
%import c64utils
|
||||
%import mathlib
|
||||
%option enable_floats
|
||||
;%import mathlib
|
||||
;%option enable_floats
|
||||
|
||||
~ main {
|
||||
|
||||
;c64scr.PLOT(screenx(x), screeny(y)) ; @todo fix argument calculation???!!!
|
||||
;@todo implement the various byte/word division routines.
|
||||
|
||||
;c64scr.PLOT(screenx(x), screeny(y)) ; @todo fix argument calculation of parameters ???!!!
|
||||
|
||||
|
||||
sub start() {
|
||||
|
||||
|
||||
byte[4] ba = [-1,2,-10,30]
|
||||
ubyte[4] uba = [4,200,10,15]
|
||||
word[5] wa = [400,-200,-1000,9999,1500]
|
||||
uword[7] uwa = [333,42,9999,12,150,1000,4000]
|
||||
float[6] fa = [-2.22, 3.33, -5.55, 1.11, 9999.99, -999.99]
|
||||
c64scr.print(" X=")
|
||||
c64scr.print_ub(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
byte bmin = min(ba)
|
||||
byte bmax = max(ba)
|
||||
ubyte ubmin = min(uba)
|
||||
ubyte ubmax = max(uba)
|
||||
word wmin = min(wa)
|
||||
word wmax = max(wa)
|
||||
uword uwmin = min(uwa)
|
||||
uword uwmax = max(uwa)
|
||||
float fmin = min(fa)
|
||||
float fmax = max(fa)
|
||||
|
||||
c64scr.print_w(wmin)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_w(wmax)
|
||||
word w = c64utils.str2word("000")
|
||||
c64scr.print_w(w)
|
||||
c64.CHROUT('\n')
|
||||
w = c64utils.str2word("1")
|
||||
c64scr.print_w(w)
|
||||
c64.CHROUT('\n')
|
||||
w = c64utils.str2word("-15000")
|
||||
c64scr.print_w(w)
|
||||
c64.CHROUT('\n')
|
||||
w = c64utils.str2word("15000")
|
||||
c64scr.print_w(w)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_uw(uwmin)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_uw(uwmax)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
c64scr.print_b(bmin)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_b(bmax)
|
||||
uword uw = c64utils.str2uword("0")
|
||||
c64scr.print_uw(uw)
|
||||
c64.CHROUT('\n')
|
||||
uw = c64utils.str2uword("1")
|
||||
c64scr.print_uw(uw)
|
||||
c64.CHROUT('\n')
|
||||
uw = c64utils.str2uword("15000")
|
||||
c64scr.print_uw(uw)
|
||||
c64.CHROUT('\n')
|
||||
uw = c64utils.str2uword("65522")
|
||||
c64scr.print_uw(uw)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(ubmin)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_ub(ubmax)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
c64flt.print_f(fmin)
|
||||
c64.CHROUT(',')
|
||||
c64flt.print_f(fmax)
|
||||
byte b = c64utils.str2byte("0")
|
||||
c64scr.print_b(b)
|
||||
c64.CHROUT('\n')
|
||||
b=c64utils.str2byte("10")
|
||||
c64scr.print_b(b)
|
||||
c64.CHROUT('\n')
|
||||
b=c64utils.str2byte("-10")
|
||||
c64scr.print_b(b)
|
||||
c64.CHROUT('\n')
|
||||
b=c64utils.str2byte("-128")
|
||||
c64scr.print_b(b)
|
||||
c64.CHROUT('\n')
|
||||
b=c64utils.str2byte("127")
|
||||
c64scr.print_b(b)
|
||||
c64.CHROUT('\n')
|
||||
c64.CHROUT('\n')
|
||||
|
||||
ubyte ub = c64utils.str2ubyte("0")
|
||||
c64scr.print_ub(ub)
|
||||
c64.CHROUT('\n')
|
||||
ub=c64utils.str2ubyte("10")
|
||||
c64scr.print_ub(ub)
|
||||
c64.CHROUT('\n')
|
||||
ub=c64utils.str2ubyte("10")
|
||||
c64scr.print_ub(ub)
|
||||
c64.CHROUT('\n')
|
||||
ub=c64utils.str2ubyte("128")
|
||||
c64scr.print_ub(ub)
|
||||
c64.CHROUT('\n')
|
||||
ub=c64utils.str2ubyte("255")
|
||||
c64scr.print_ub(ub)
|
||||
c64.CHROUT('\n')
|
||||
c64.CHROUT('\n')
|
||||
|
||||
c64scr.print(" X=")
|
||||
c64scr.print_ub(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
; ub3 = 200/67 as ubyte
|
||||
; ub3 = 200//67
|
||||
; c64scr.print_ub(ub3)
|
||||
; c64.CHROUT('\n')
|
||||
; ub3 = ub1/ub2
|
||||
; c64scr.print_ub(ub3)
|
||||
; c64.CHROUT('\n')
|
||||
; ub3 = ub1//ub2
|
||||
; c64scr.print_ub(ub3)
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
; uw3 = 2000/67 as uword
|
||||
; c64scr.print_uw(uw3)
|
||||
; c64.CHROUT('\n')
|
||||
; uw3 = 2000//67
|
||||
; c64scr.print_uw(uw3)
|
||||
; c64.CHROUT('\n')
|
||||
; uw3 = uw1/uw2
|
||||
; c64scr.print_uw(uw3)
|
||||
; c64.CHROUT('\n')
|
||||
; uw3 = uw1//uw2
|
||||
; c64scr.print_uw(uw3)
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
|
||||
; const byte width=20
|
||||
; word w1
|
||||
; byte b1
|
||||
; ubyte ub1
|
||||
; float x = 3.45
|
||||
; b1 = fintb(x * flt(width)/4.2) + width//2
|
||||
; c64scr.print_b(b1)
|
||||
; c64.CHROUT('\n')
|
||||
; b1 = fintb(x/4.2 * flt(width)) + width//2
|
||||
; c64scr.print_b(b1)
|
||||
; c64.CHROUT('\n')
|
||||
; ub1 = b2ub(fintb(x * flt(width)/4.2) + width//2)
|
||||
; c64scr.print_ub(ub1)
|
||||
; c64.CHROUT('\n')
|
||||
; ub1 = b2ub(fintb(x/4.2 * flt(width)) + width//2)
|
||||
; c64scr.print_ub(ub1)
|
||||
; c64.CHROUT('\n')
|
||||
; w1 = fintw(x * flt(width)/4.2) + width//2
|
||||
; c64scr.print_w(w1)
|
||||
; c64.CHROUT('\n')
|
||||
; w1 = fintw(x/4.2 * flt(width)) + width//2
|
||||
; c64scr.print_w(w1)
|
||||
; c64.CHROUT('\n')
|
||||
;uw1 = w2uw(fintw(x * flt(width)/4.2) + width//2) ; @todo w2uw
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,6 +270,7 @@ interface IAstProcessor {
|
||||
}
|
||||
|
||||
fun process(typecastExpression: TypecastExpression): IExpression {
|
||||
typecastExpression.expression = typecastExpression.expression.process(this)
|
||||
return typecastExpression
|
||||
}
|
||||
}
|
||||
@ -477,7 +478,7 @@ private class GlobalNamespace(override val name: String,
|
||||
override fun linkParents(parent: Node) {}
|
||||
|
||||
override fun lookup(scopedName: List<String>, statement: Node): IStatement? {
|
||||
if(scopedName.last() in BuiltinFunctions) {
|
||||
if(scopedName.size==1 && scopedName[0] in BuiltinFunctions) {
|
||||
// builtin functions always exist, return a dummy statement for them
|
||||
val builtinPlaceholder = Label("builtin::${scopedName.last()}", statement.position)
|
||||
builtinPlaceholder.parent = ParentSentinel
|
||||
|
@ -436,8 +436,11 @@ class AstChecker(private val namespace: INameScope,
|
||||
val sourceDatatype: DataType? = assignment.value.resultingDatatype(namespace, heap)
|
||||
if(sourceDatatype==null) {
|
||||
if(assignment.targets.size<=1) {
|
||||
if (assignment.value is FunctionCall)
|
||||
if (assignment.value is FunctionCall) {
|
||||
val targetStmt = (assignment.value as FunctionCall).target.targetStatement(namespace)
|
||||
if(targetStmt!=null)
|
||||
checkResult.add(ExpressionError("function call doesn't return a suitable value to use in assignment", assignment.value.position))
|
||||
}
|
||||
else
|
||||
checkResult.add(ExpressionError("assignment value is invalid or has no proper datatype", assignment.value.position))
|
||||
}
|
||||
|
@ -1388,7 +1388,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
AX -> {
|
||||
// deal with register pair AX: target = A + X*256
|
||||
val targetDt = target.determineDatatype(namespace, heap, parent)
|
||||
if(targetDt!=DataType.UWORD)
|
||||
if(targetDt!=DataType.UWORD && targetDt!=DataType.WORD)
|
||||
throw CompilerException("invalid target datatype for registerpair $targetDt")
|
||||
prog.instr(Opcode.PUSH_REGAX_WORD)
|
||||
popValueIntoTarget(target, targetDt)
|
||||
@ -1396,7 +1396,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
AY -> {
|
||||
// deal with register pair AY: target = A + Y*256
|
||||
val targetDt = target.determineDatatype(namespace, heap, parent)
|
||||
if(targetDt!=DataType.UWORD)
|
||||
if(targetDt!=DataType.UWORD && targetDt!=DataType.WORD)
|
||||
throw CompilerException("invalid target datatype for registerpair $targetDt")
|
||||
prog.instr(Opcode.PUSH_REGAY_WORD)
|
||||
popValueIntoTarget(target, targetDt)
|
||||
@ -1404,7 +1404,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
XY -> {
|
||||
// deal with register pair XY: target = X + Y*256
|
||||
val targetDt = target.determineDatatype(namespace, heap, parent)
|
||||
if(targetDt!=DataType.UWORD)
|
||||
if(targetDt!=DataType.UWORD && targetDt!=DataType.WORD)
|
||||
throw CompilerException("invalid target datatype for registerpair $targetDt")
|
||||
prog.instr(Opcode.PUSH_REGXY_WORD)
|
||||
popValueIntoTarget(target, targetDt)
|
||||
|
@ -425,10 +425,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
if (ins.arg!!.numericValue() in syscallsForStackVm.map { it.callNr })
|
||||
throw CompilerException("cannot translate vm syscalls to real assembly calls - use *real* subroutine calls instead. Syscall ${ins.arg.numericValue()}")
|
||||
val call = Syscall.values().find { it.callNr==ins.arg.numericValue() }
|
||||
when(call) {
|
||||
Syscall.FUNC_STR2UBYTE, Syscall.FUNC_STR2UWORD -> " jsr prog8_lib.func_str2uword"
|
||||
else -> " jsr prog8_lib.${call.toString().toLowerCase()}"
|
||||
}
|
||||
" jsr prog8_lib.${call.toString().toLowerCase()}"
|
||||
}
|
||||
Opcode.BREAKPOINT -> {
|
||||
breakpointCounter++
|
||||
|
@ -54,11 +54,6 @@ val BuiltinFunctions = mapOf(
|
||||
"clear_carry" to FunctionSignature(false, emptyList(), null),
|
||||
"set_irqd" to FunctionSignature(false, emptyList(), null),
|
||||
"clear_irqd" to FunctionSignature(false, emptyList(), null),
|
||||
"str2byte" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.BYTE),
|
||||
"str2ubyte" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.UBYTE),
|
||||
"str2word" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.WORD),
|
||||
"str2uword" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.UWORD),
|
||||
"str2float" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.FLOAT),
|
||||
"vm_write_memchr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", setOf(DataType.UWORD))), null),
|
||||
"vm_write_memstr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", setOf(DataType.UWORD))), null),
|
||||
"vm_write_num" to FunctionSignature(false, listOf(BuiltinFunctionParam("number", NumericDatatypes)), null),
|
||||
|
@ -40,11 +40,6 @@ enum class Syscall(val callNr: Short) {
|
||||
FUNC_RND(89), // push a random byte on the stack
|
||||
FUNC_RNDW(90), // push a random word on the stack
|
||||
FUNC_RNDF(91), // push a random float on the stack (between 0.0 and 1.0)
|
||||
FUNC_STR2BYTE(100),
|
||||
FUNC_STR2UBYTE(101),
|
||||
FUNC_STR2WORD(102),
|
||||
FUNC_STR2UWORD(103),
|
||||
FUNC_STR2FLOAT(104),
|
||||
FUNC_LEN_STR(105),
|
||||
FUNC_LEN_STRP(106),
|
||||
FUNC_LEN_STRS(107),
|
||||
@ -1568,38 +1563,6 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
val value = heap.get(iterable.heapId)
|
||||
evalstack.push(Value(DataType.UBYTE, if (value.array!!.all { v -> v != 0 }) 1 else 0))
|
||||
}
|
||||
Syscall.FUNC_STR2BYTE -> {
|
||||
val strvar = evalstack.pop()
|
||||
val str = heap.get(strvar.heapId) // TODO CHECK
|
||||
val y = str.str!!.trim().trimEnd('\u0000')
|
||||
evalstack.push(Value(DataType.BYTE, y.toShort()))
|
||||
}
|
||||
Syscall.FUNC_STR2UBYTE -> {
|
||||
val heapId = evalstack.pop().integerValue()
|
||||
val str = heap.get(heapId)
|
||||
val y = str.str!!.trim().trimEnd('\u0000')
|
||||
val number = (y.toInt() and 255).toShort()
|
||||
evalstack.push(Value(DataType.UBYTE, number))
|
||||
}
|
||||
Syscall.FUNC_STR2WORD -> {
|
||||
val heapId = evalstack.pop().integerValue()
|
||||
val str = heap.get(heapId)
|
||||
val y = str.str!!.trim().trimEnd('\u0000')
|
||||
evalstack.push(Value(DataType.WORD, y.toInt()))
|
||||
}
|
||||
Syscall.FUNC_STR2UWORD -> {
|
||||
val heapId = evalstack.pop().integerValue()
|
||||
val str = heap.get(heapId)
|
||||
val y = str.str!!.trim().trimEnd('\u0000')
|
||||
val number = y.toInt() and 65535
|
||||
evalstack.push(Value(DataType.UWORD, number))
|
||||
}
|
||||
Syscall.FUNC_STR2FLOAT -> {
|
||||
val heapId = evalstack.pop().integerValue()
|
||||
val str = heap.get(heapId)
|
||||
val y = str.str!!.trim().trimEnd('\u0000')
|
||||
evalstack.push(Value(DataType.FLOAT, y.toDouble()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -565,21 +565,6 @@ rndw()
|
||||
rndf()
|
||||
returns a pseudo-random float between 0.0 and 1.0
|
||||
|
||||
str2byte(s)
|
||||
converts string s into the numeric value that s represents (signed byte).
|
||||
|
||||
str2ubyte(s)
|
||||
converts string s into the numeric value that s represents (unsigned byte).
|
||||
|
||||
str2word(s)
|
||||
converts string s into the numeric value that s represents (signed word).
|
||||
|
||||
str2uword(s)
|
||||
converts string s into the numeric value that s represents (unsigned word).
|
||||
|
||||
str2float(s)
|
||||
converts string s into the numeric value that s represents (float).
|
||||
|
||||
lsl(x)
|
||||
Shift the bits in x (byte or word) one position to the left.
|
||||
Bit 0 is set to 0 (and the highest bit is shifted into the status register's Carry flag)
|
||||
|
@ -188,6 +188,97 @@ asmsub uword2decimal (uword value @ AY) -> clobbers(A,X,Y) -> () {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
; @todo this is python code for a str-to-ubyte function that doesn't use the basic rom:
|
||||
;def str2ubyte(s, slen):
|
||||
; hundreds_map = {
|
||||
; 0: 0,
|
||||
; 1: 100,
|
||||
; 2: 200
|
||||
; }
|
||||
; digitvalue = 0
|
||||
; result = 0
|
||||
; if slen==0:
|
||||
; return digitvalue
|
||||
; digitvalue = ord(s[slen-1])-48
|
||||
; slen -= 1
|
||||
; if slen==0:
|
||||
; return digitvalue
|
||||
; result = digitvalue
|
||||
; digitvalue = 10 * (ord(s[slen-1])-48)
|
||||
; result += digitvalue
|
||||
; slen -= 1
|
||||
; if slen==0:
|
||||
; return result
|
||||
; digitvalue = hundreds_map[ord(s[slen-1])-48]
|
||||
; result += digitvalue
|
||||
; return result
|
||||
|
||||
asmsub str2uword(str string @ AY) -> clobbers() -> (uword @ AY) {
|
||||
%asm {{
|
||||
;-- convert string (address in A/Y) to uword number in A/Y
|
||||
; @todo don't use the (slow) kernel floating point conversion
|
||||
sta $22
|
||||
sty $23
|
||||
jsr _strlen2233
|
||||
tya
|
||||
stx c64.SCRATCH_ZPREGX
|
||||
jsr c64.FREADSTR ; string to fac1
|
||||
jsr c64.GETADR ; fac1 to unsigned word in Y/A
|
||||
ldx c64.SCRATCH_ZPREGX
|
||||
sta c64.SCRATCH_ZPREG
|
||||
tya
|
||||
ldy c64.SCRATCH_ZPREG
|
||||
rts
|
||||
|
||||
_strlen2233
|
||||
;-- return the length of the (zero-terminated) string at $22/$23, in Y
|
||||
ldy #0
|
||||
- lda ($22),y
|
||||
beq +
|
||||
iny
|
||||
bne -
|
||||
+ rts
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub str2word(str string @ AY) -> clobbers() -> (word @ AY) {
|
||||
%asm {{
|
||||
;-- convert string (address in A/Y) to signed word number in A/Y
|
||||
; @todo don't use the (slow) kernel floating point conversion
|
||||
sta $22
|
||||
sty $23
|
||||
jsr str2uword._strlen2233
|
||||
tya
|
||||
stx c64.SCRATCH_ZPREGX
|
||||
jsr c64.FREADSTR ; string to fac1
|
||||
jsr c64.FTOSWORDYA ; fac1 to unsigned word in Y/A
|
||||
ldx c64.SCRATCH_ZPREGX
|
||||
sta c64.SCRATCH_ZPREG
|
||||
tya
|
||||
ldy c64.SCRATCH_ZPREG
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub str2ubyte(str string @ AY) -> clobbers(Y) -> (ubyte @ A) {
|
||||
%asm {{
|
||||
;-- convert string (address in A/Y) to ubyte number in A
|
||||
; @todo don't use the (slow) kernel floating point conversion
|
||||
jmp str2uword
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub str2byte(str string @ AY) -> clobbers(Y) -> (byte @ A) {
|
||||
%asm {{
|
||||
;-- convert string (address in A/Y) to byte number in A
|
||||
; @todo don't use the (slow) kernel floating point conversion
|
||||
jmp str2word
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
; @todo string to 32 bit unsigned integer http://www.6502.org/source/strings/ascii-to-32bit.html
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user