;------------------------------------------------------------------------------------;
; Token recognition Block ;
;------------------------------------------------------------------------------------;
subleq 0, 0, @start ;Reserve the memory for the program
subleq 0, 0, 0
subleq 0, 0, 0
subleq 0, 0, 0
subleq 0, 0, 0
subleq 0, 0, 0
subleq 0, 0, 0
@start:
subleq 2, 2 ;Clear the first instruction
@readToken:
subleq @t, @t
subleq @t, @IN ;Check what word is coming (\0 \n . s)
subleq @a, @a
subleq @a, @t, 0 ;if \0 jump to the begining of a stored program
subleq @a, @p10, @readToken ;if \n read another line
subleq @a, @p36, @dotToken ;if '.' .data token
subleq @a, @p69, @sToken ;if 's' subleq token
;Random numbers because it's faster to subtract differences between symbols
;instead of comparing to each one
;10 = 10-0 ;36 = 46-10 ;69 = 115-46 (\n=10 .=46 s=115)
@dotToken:
subleq @i, @p1 ;Set loop variable to 1 (only 1 number after .data)
subleq @a, @p4 ;Read 5 more symbols ."data "
@dotInLoop: ;By the time we get here @a is zero so no need to clear it
subleq @t, @IN
subleq @a, @n1, @dotInLoop
subleq @a, @a, @readNumber
@sToken:
subleq @i, @p3 ;Set loop variable to 3 (3 numbers after subleq)
subleq @a, @p5 ;Read 6 more symbols s"ubleq "
@sInLoop: ;By the time we get here @a is zero so no need to clear it
subleq @t, @IN
subleq @a, @n1, @sInLoop
subleq @a, @a, @readNumber
;------------------------------------------------------------------------------------;
; Number parsing Block ;
;------------------------------------------------------------------------------------;
@readNumber:
subleq @a, @IN ;@a is cleared after we get a token
subleq @t, @t
subleq @t, @a, @endOfNum
subleq @t, @p32, @endOfNum ;Check if less than or equal to 32. \n or space
subleq @t, @p13, @foundMinus ;Check if minus
subleq @a,@a, @skipMinus ;both sets @a to zero and skips the negative flag
@foundMinus:
subleq @isPositive, @n1 ;If there was a minus in the number set the minus flag and read another number
subleq @a, @a, @readNumber ;This check is made in every digit, inefficient but short
@skipMinus:
;To add digit A to the end of number B And get new number C
;C = B * 10 + A
subleq @t, @p3 ;finish converting ascii to int
subleq @ml, @p9 ;Set mul loop variable to 9. Multiply 9 times. Not 10. The 10th part is added after the loop
@mulLoop: ;Since @ml always ends up being 1 at the end of the loop, no need to clear it
subleq @a,@numb
subleq @ml, @n1, @mulLoop
subleq @numb, @a ;Add the multiplied by 9 part of a number to itself.
subleq @numb, @t ;Add the next digit to the number
subleq @a,@a, @readNumber ;Read another number
;------------------------------------------------------------------------------------;
; Write to memory Block ;
;------------------------------------------------------------------------------------;
@endOfNum:
subleq @t, @t
subleq @isPositive, @p0, @skipNegative ;Negate a number if a flag is set
@neg:
subleq @isPositive, @isPositive
subleq @t, @numb
subleq @a, @a
subleq @a, @t
subleq @numb, @a ;I think this can be shorter somehow
subleq @numb, @a
@skipNegative:
subleq @t, @numb ;Check if number is 255
subleq @t, @n1, @ch255 ;The program shouldn't jump to 255 when it ends
subleq @t, @t, @writeMem
@ch255:
subleq @t, @n1, @writeMem
subleq @numb, @numb ;found 255
subleq @numb, @resetPos ;Instead it jumps to the @resetLoop lable to start the process over
subleq @t, @t, @writeMem
@writeMem:
subleq 0, @numb ;Write the number to the memory
subleq @writeMem, @n1 ;increment the memory pointer
subleq @resetLoopPtr, @n1 ;increment pointers for clearing memory
subleq @resetLoopPtr+1, @n1
subleq @len, @p1 ;Count how long the program is
subleq @numb, @numb
subleq @a, @a
subleq @i,@n1, @readNumber ;While have more numbers, keep reading
subleq @t, @t, @readToken ;Read another token if don't have more numbers
;------------------------------------------------------------------------------------;
; Reset Block ;
;------------------------------------------------------------------------------------;
@resetLoop:
subleq @writeMem, @p1
subleq @resetLoopPtr, @p1 ;Decrement all pointers
subleq @resetLoopPtr+1, @p1
@resetLoopPtr:
subleq 0, 0 ;Clear the memory
subleq @len, @n1, @resetLoop
subleq @t, @t, @readToken ;Go back to reading new tokens for a new program
@numb: .data 0 ;For storing the number
@t: .data 0
@a: .data 0
@i: .data 1 ;Input number count loop
@ml: .data 1 ;Multiplication loop
@len: .data 1 ;Program length
@isPositive: .data 0 ;Flag for negative numbers
@n1: .data -1
@p0: .data 0
@p1: .data 1
@p3: .data 3
@p4: .data 4
@p5: .data 5 ;Constants sea
@p9: .data 9
@p10: .data 10
@p13: .data 13
@p32: .data 32
@p36: .data 36
@p69: .data 69
@resetPos: .data -64 ;Location of a @resetLoop