diff --git a/m0asm.pm b/m0asm.pm new file mode 100644 index 0000000000..1c2854be49 --- /dev/null +++ b/m0asm.pm @@ -0,0 +1,196 @@ +#! parrot-nqp + +# workaround nqp-rx not generating :main + + + + +MAIN(); + +sub MAIN() { + + #data structures: + # * directory + + # these things can be assembled witout external depencencies + # * vartable + # * metadta seg + # * bytecode seg + + #loop: + + my $curr_seg := 'start'; + my @chunks := (); + my %curr_chunk := {}; + my $process; + + my $s := pir::new('FileHandle').readall('hello.0bc'); + for pir::split__pss("\n", $s) -> $line { + + if (pir::index__iss($line, '.') == 0) { + grammar DOT_LINE { + rule TOP { "." \s* ['"' '"']? $$ } + token type { [ "chunk" | "variables" | "metadata" | "bytecode" ] } + token name { <.ident> } + } + my $match := DOT_LINE.parse($line); + #say($line); + #_dumper($match); + + if ($match eq 'chunk') { + @chunks.push(%curr_chunk) if %curr_chunk; + %curr_chunk := {}; + %curr_chunk := ~$match[0]; + } + elsif ($line ~~ /variables/) { + #initialize the variables segment + $process := process_variable; + %curr_chunk := ''; + %curr_chunk := 0; + } + elsif ($line ~~ /metadata/) { + #initialize the metadata segment + $process := process_metadata; + } + elsif ($line ~~ /bytecode/) { + #finalize the metadata segment + #initialize the bytecode segment + $process := process_bytecode; + } + } + $process($line, %curr_chunk) if $process; + } + #finalize the bytecode segment +} + +sub process_variable($line, %chunk) { + + grammar VAR_LINE { + rule TOP { } + token var_num { } + token data { [ | | | ] } + token hex { '0x' []+ } + token int { \d+ } + token string { '"' + '"' } + token float { '12341234e32342' } + } + + my $match := VAR_LINE.parse($line); + my $bits; + + if $match { + _dumper($match); + $bits := convert_hex(pir::join('',$match)); + } + elsif $match { + say("int thingy"); + } + elsif $match { + say("string thingy"); + } + elsif $match { + say("float thingy"); + } + #convert it into bytes + #update the size of the vars body +} + +sub convert_hex($data) { + my $bits := pir::new('ByteBuffer'); + while pir::length($data) >= 2 { + my $char0 := pir::substr($data, 0, 1); + my $char1 := pir::substr($data, 1, 2); + $data := pir::substr($data, 2); + my $byte := 16*hexval($char0) + hexval($char1); + } +} + +sub hexval($c) { + my $ord_c := pir::ord($c); + my $ord_0 := pir::ord('0'); + my $ord_9 := pir::ord('9'); + my $ord_a := pir::ord('a'); + my $ord_f := pir::ord('f'); + + $ord_0 <= $ord_c && $ord_c <= $ord_9 ?? + $ord_c - $ord_0 !! + $ord_a <= $ord_c && $ord_c <= $ord_f ?? + $ord_c - $ord_a + 10 !! + 0; +} + + + +sub process_metadata($line, %chunk) { + #say("processing metadata on line '$line'"); + +} + +sub process_bytecode($line, %chunk) { + #say("processing bytecode on line '$line'"); + +} + +sub reg_map() { + my %h; + %h := 0x00; + %h := 0x01; + %h := 0x02; + %h := 0x03; + %h := 0x04; + %h := 0x05; + %h := 0x06; + %h := 0x07; + + my $i := 0; + while ($i <= 61) { + %h{"I"~ ~$i} := $i + 8; + %h{"N"~ ~$i} := $i + 70; + %h{"S"~ ~$i} := $i + 132; + %h{"P"~ ~$i} := $i + 194; + } + + %h; +} + +sub ops_map() { + my %h; + %h := 0x00; + %h := 0x01; + %h := 0x02; + %h := 0x03; + %h := 0x04; + %h := 0x05; + %h := 0x06; + %h := 0x07; + %h := 0x08; + %h := 0x09; + %h := 0x0A; + %h := 0x0B; + %h := 0x0C; + %h := 0x0D; + %h := 0x0E; + %h := 0x0F; + %h := 0x10; + %h := 0x11; + %h := 0x12; + %h := 0x13; + %h := 0x14; + %h := 0x15; + %h := 0x16; + %h := 0x17; + %h := 0x18; + %h := 0x19; + %h := 0x1A; + %h := 0x1B; + %h := 0x1C; + %h := 0x1D; + %h := 0x1E; + %h := 0x1F; + %h := 0x20; + %h := 0x21; + %h := 0x22; + %h := 0x23; + %h; +}; +