News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_zhulien

A mini lowlevel language portable that generates ok code for some platforms

Started by zhulien, 17:58, 08 July 20

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

zhulien


A mini lowlevel language portable that generates ok code for some platforms


Example:


// with whitespace (as you would program it)


hw: 'Hello, World!',0
inline txt_out_char: /- -a8 +/ [#bb5a].
inline txt_out_str: /- -a16 +/ { a8=(a16) .z +a16 [txt_out_char, +a8] -a16 a16++ }.
main: a16=hw [txt_out_str, +a16].


// without whitespace (if you prefer)


hw:'Hello, World!',0
inline txt_out_char:/--a8v/[#bb5a].
inline txt_out_str:/--a16+/{a8=(a16).z+a16[txt_out_char,+a8]-a16a16++}.
main:a16=hw[txt_out_str,+a16].


// with inlines processed


hw:'Hello, World!',0
main:a16=hw{a8=(a16).z+a16[#bb5a]-a16a16++}.


// generated output on z80


ld hl,hw
loop1:
ld a,(hl)
jr z,loop1e
push hl
call #bb5a
pop hl
inc hl
jr loop1
loop1e:
ret
hw: defs 'Hello, World!',0






explanation of above:


command set:


/- and +/ is what parameters are surrounded by but itself has a meaning too
- means pop
+ means push
[] means call
. means return
= means assign one register to another
{} means we have an infinite loop that can be broken out of
.z means break from the loop if zero
++ increment
-- decrement


we have a8 for 8bit accumulator
we have a16 for 16bit accumulator
we can have additional 8bit and 16bit virtual registers that may or may not map to real registers for code porability




We have strings which get turned into labels automatically.


hw: 'Hello, World!',0


The keyword inline is a modifier, it means don't "call a function" but rather substitute the entire function inline where ever it is used.  In this case, the function is called txt_out_char.  The colon after txt_out_char indicates a function declaration.


/- means put the top stack item into a storage location, +/ means put it back onto the stack - but...
they only take effect if the keyword 'inline' is removed, there-by making it a callable function again.  It means the same code for inline and not.  /- -a8 +/ means basically take the first value under the return address if a called function. [#bb5a] means call #bb5a on a z80.


inline txt_out_char: /- -a8 +/ [#bb5a].


inline txt_out_char: -a8 [#bb5a].  <--- equivalent of the line above, but it can never be used not inline.


inline txt_out_str: /- -a16 +/ { a8=(a16) .z +a16 [txt_out_char, +a8] -a16 a16++ }.
main: a16=hw [txt_out_str, +a16].






line by line assembly:


hw: 'Hello, World!',0


assembles to:


hw: defs 'Hello, World!',0




Pass 1 converts the inlines to in-place code, this in-line substituion knows what parameters are between the /- and +/ so... we no longer needs to pass them in the call.


inline txt_out_char: /- -a8 +/ [#bb5a].
inline txt_out_str: /- -a16 +/ { a8=(a16) .z +a16 [txt_out_char, +a8] -a16 a16++ }.
main: a16=hw [txt_out_str, +a16].


after in-line code substitutions:


main: a16=hw { a8=(a16) .z +a16 [#bb5a] -a16 a16++ }.


then final compilation:


      ld hl,hw         ; a16=hw
loop1:                  ; {
      ld a,(hl)         ; .z
      jr z,loop1e         ; .z
      push hl            ; +a16
      call #bb5a         ; [#bb5a]
      pop hl            ; -a16
      inc hl            ; a16++
      jr loop1         ; }
loop1e:                  ; .z
      ret               ; .
      hw: defs 'Hello, World!',0


Of course we would need a few more operations like adding, subtracting, bit operations.


In the end I didn't develop this because I thought it is just as easy to code in assembler but... of course we lose the ability to code cross platform, eg: z80 and 6502.


AMSDOS

At the moment in my little tbas language, 'print' supports character and string, but not a value of a byte variable. I think it could be a good way of extending the rest of the character set, which wouldn't be that hard to do in assembly.


For instance:



let b(0)=224
print b(0)



becomes:



ld a,224
ld (&a000),a
ld a,(&a000)
call &bb5a



with the language automatically working out the address of b(0), based on the number, so b(0) to b(255) are worked out as &a000 to &a0ff.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Powered by SMFPacks Menu Editor Mod