Hot on the heels of writing an assembler I decided to take my learning and have a go at a higher level language with C-family syntax.
To be honest the syntax so far looks more like groovy (or even Kotlin) , because of the lack of typing and the use of the "var" keyword and the "main()" function approach looks like Kotlin.
This is being written in Scala because it's a great language for this kind of thing due to its pattern matching and also it's Parser Combinator library which makes parsing a breeze (mostly).
An example of a countdown program is shown below.
The steps in the automated tests are
- compile the "SPAM-C" code into Asm files
- assemble the generated Asm file into ROM images
- run the ROM images in the verilog simulator
These steps happen automatically in the test and this has helped spot loads of potential issues along the way.
SPAM-C code .....
def main() {
var a=10;
while(a>0) {
var a=a-1;
putchar(a)
}
}
The compiler spits out this assembler which is then assembled and the verilog simulator invoked so I get to see the program running too.
root_function_main_a: EQU 0
; (0) ENTER root_function_main @ function
; (1) ENTER root_function_main @ statementVar
[:root_function_main_a] = 10
; (1) EXIT root_function_main @ statementVar
; (1) ENTER root_function_main_whileCond1 @ whileCond
root_function_main_whileCond1__2__check:
; (2) ENTER root_function_main_whileCond1 @ condition
REGA = [:root_function_main_a]
REGA = REGA PASS_A 0 _S
; (2) EXIT root_function_main_whileCond1 @ condition
PCHITMP = <:root_function_main_whileCond1__2__top
PC = >:root_function_main_whileCond1__2__top _GT
PCHITMP = <:root_function_main_whileCond1__2__bot
PC = >:root_function_main_whileCond1__2__bot
root_function_main_whileCond1__2__top:
; (2) ENTER root_function_main_whileCond1 @ statementEqVarOpConst
REGA = [:root_function_main_a]
REGA = REGA - 1
[:root_function_main_a] = REGA
; (2) EXIT root_function_main_whileCond1 @ statementEqVarOpConst
; (2) ENTER root_function_main_whileCond1_putcharN @ statementPutcharName
root_function_main_whileCond1_putcharN__wait_3:
PCHITMP = <:root_function_main_whileCond1_putcharN__transmit_4
PC = >:root_function_main_whileCond1_putcharN__transmit_4 _DO
PCHITMP = <:root_function_main_whileCond1_putcharN__wait_3
PC = <:root_function_main_whileCond1_putcharN__wait_3
root_function_main_whileCond1_putcharN__transmit_4:
UART = [:root_function_main_a]
; (2) EXIT root_function_main_whileCond1_putcharN @ statementPutcharName
PCHITMP = <:root_function_main_whileCond1__2__check
PC = >:root_function_main_whileCond1__2__check
root_function_main_whileCond1__2__bot:
; (1) EXIT root_function_main_whileCond1 @ whileCond
PCHITMP = <:root_end
PC = >:root_end
; (0) EXIT root_function_main @ function
root_end:
END
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.