diff options
| author | Drahflow <drahflow@gmx.de> | 2012-12-31 19:00:08 +0100 |
|---|---|---|
| committer | Drahflow <drahflow@gmx.de> | 2012-12-31 19:00:08 +0100 |
| commit | d7d307dc6563fe27bf43cab1e83ac21204fea6c6 (patch) | |
| tree | 13a37937bbdb8a25c953183be0b8cf61e3acc6a9 | |
| parent | ac637b1cda03446a57ca6b1f20e5e63f1c8d7d0f (diff) | |
Bytecode executing
Specifically, an empty opcode sequence is executed
for each token. Next up: Scope resolution and actually
call some of these functions.
| -rw-r--r-- | compiler/elymasAsm.ey | 134 | ||||
| -rw-r--r-- | compiler/elymasGlobal.ey | 24 | ||||
| -rw-r--r-- | compiler/standard.ey | 39 |
3 files changed, 186 insertions, 11 deletions
diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey new file mode 100644 index 0000000..f62f979 --- /dev/null +++ b/compiler/elymasAsm.ey @@ -0,0 +1,134 @@ +< + 4096 ==PAGESIZE + 16777216 ==STACKSIZE + 128 ==STACKSTART + + STACKSIZE sys .asm .alloc ==mainStack + + # global stack layout + # 0 - STACKSTART : global variables + # 0 : current stack pointer + # STACKSTART - ...: real stack + + # hex decoding + { + "(.)(.)" regex { } { "not a valid hex-string" die } ? * + { { streq }_ [ "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" ] -01 index } + -20*10* 16 mul add + } "%" defq + + # registers + { [ /rax /rcx /rdx /rbx /rsp /rbp /rsi /rdi /r8 /r9 /r10 /r11 /r12 /r13 /r14 /r15 ] streq any } /bit64 deff + { [ /eax /ecx /edx /ebx /esp /ebp /esi /edi /r8d /r9d /r10d /r11d /r12d /r13d /r14d /r15d ] streq any } /bit32 deff + { [ /ax /cx /dx /bx /sp /bp /si /di /r8w /r9w /r10w /r11w /r12w /r13w /r14w /r15w ] streq any } /bit16 deff + { [ /al /cl /dl /bl /spl /ah /bpl /ch /sil /dh /dil /bh /r8b /r9b /r10b /r11b /r12b /r13b /r14b /r15b ] streq any } /bit8 deff + + { { streq any }_ ==reg + [ + [ /al /ax /eax /rax /none ] + [ /cl /cx /ecx /rcx ] + [ /dl /dx /edx /rdx ] + [ /bl /bx /ebx /rbx ] + [ /spl /ah /sp /esp /rsp ] + [ /bpl /ch /bp /ebp /rbp ] + [ /sil /si /esi /rsi ] + [ /dil /di /edi /rdi ] + [ /r8b /r8w /r8d /r8 ] + [ /r9b /r9w /r9d /r9 ] + [ /r10b /r10w /r10d /r10 ] + [ /r11b /r11w /r11d /r11 ] + [ /r12b /r12w /r12d /r12 ] + [ /r13b /r13w /r13d /r13 ] + [ /r14b /r14w /r14d /r14 ] + [ /r15b /r15w /r15d /r15 ] + ] reg index + _ 1 neg gt assert + } /regno deff + + # encoding a REX prefix + { ==b ==x ==r ==w + %40 + w 0 gt %08 mul add + r regno %08 band 0 gt %04 mul add + x regno %08 band 0 gt %02 mul add + b regno %08 band 0 gt %01 mul add + } /rex deff + + { =mem =reg + mem [ /spl /sp /esp /rsp /bpl /bp /ebp /rbp ] streq any not assert + + %00 + mem regno %07 band add + reg regno 8 mul %38 band add + } /modrm00 deff + + { 8 { _ 256 mod -01 256 div } rep -- } /imm64 deff + { 4 { _ 256 mod -01 256 div } rep -- } /imm32 deff + { 2 { _ 256 mod -01 256 div } rep -- } /imm16 deff + { } /imm8 deff + + # instructions + { ==reg ==i + reg bit64 assert + + 1 /none /none reg rex + %B8 reg regno %07 band add + i imm64 + } /movqImmReg deff + + { ==reg ==mem + reg bit64 assert + mem bit64 assert + + 1 reg /none mem rex + %89 + reg mem modrm00 + } /movqMemReg deff + + { ==mem ==reg + reg bit64 assert + mem bit64 assert + + 1 reg /none mem rex + %8B + reg mem modrm00 + } /movqRegMem deff + + { =reg + reg regno %07 gt { 1 /none /none reg rex } rep + %58 reg regno %07 band add + } /popq deff + + { =reg + reg regno %07 gt { 1 /none /none reg rex } rep + %50 reg regno %07 band add + } /pushq deff + + { + %C3 + } /retn deff + + # take an array of instruction bytes and execute it on the given stack + { ==stack ==opcodes + [ + /rbx pushq + stack /rbx movqImmReg + /rbx /rsp movqMemReg + ] opcodes [ + stack /rbx movqImmReg + /rsp /rbx movqRegMem + /rbx popq + retn + ] cat cat =opcodes + + opcodes len 1 sub PAGESIZE div 1 add PAGESIZE mul sys .asm .alloc /codearea defv + codearea .base ==i + opcodes { i sys .asm .poke i 1 add =i } each + codearea .base sys .asm .execute + codearea .free + } /executeOn deff + + { mainStack .base executeOn } /execute deff +> /assembler defv + +# vim: syn=elymas diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey index 237178d..c339ede 100644 --- a/compiler/elymasGlobal.ey +++ b/compiler/elymasGlobal.ey @@ -1,38 +1,42 @@ +"elymasAsm.ey" include + 0 /TOKINT defv 1 /TOKSTR defv 2 /TOKID defv -{ /f deff _1 /s defv regex { f } { s } ? * } /rxparse deff +{ /f deff -101 /s defv regex { f } { s } ? * } /rxparse deff { " " cat { < /type defv /value defv > } /token deff [ -01 { _ "" streq not } { - 0 /any defv { /f deff any { - } { { 1 =any f } rxparse } ? * } /parse deff + 0 /matched defv { /f deff matched { -- } { { 1 =matched f } rxparse } ? * } /parse deff "^ (.*)" { } parse "^#" { "" } parse "^(\\d+) +(.*)" { TOKINT token -01 } parse "\"(.*)" { "" /str defv - { _ "^\"(.*)" regex { --0 0 } { 1 } ? * } { - 0 /strany defv { /f deff strany { - } { { 1 =strany f } rxparse } ? * } /strparse deff + { _ "^\"(.*)" regex { -01 -- 0 } { 1 } ? * } { + 0 /strmatched defv { /f deff strmatched { -- } { { 1 =strmatched f } rxparse } ? * } /strparse deff "^\\\\\\\\(.*)" { str "\\" cat =str } strparse "^\\\\n(.*)" { str "\n" cat =str } strparse "^\\\\\"(.*)" { str "\"" cat =str } strparse "^([^\"\\\\])(.*)" { str -01 cat =str } strparse - strany not { "Tokenization of string-like failed" die } rep + strmatched not { "Tokenization of string-like failed" die } rep } loop str TOKSTR token -01 } parse - "^([^a-zA-Z ]+)([a-zA-Z]+) +(.*)" { -201 TOKSTR token " " -1203 cat cat } parse - "^([a-zA-Z]+|[^a-zA-Z ]+) +(.*)" { TOKID token -01 } parse - any not { "Tokenization failed" die } rep - } loop - ] + "^([^a-zA-Z0-9 ]+)([a-zA-Z0-9][^ ]*) +(.*)" { -201 TOKSTR token " " -1203 cat cat } parse + "^([a-zA-Z0-9]+|[^a-zA-Z0-9 ]+) +(.*)" { TOKID token -01 } parse + + matched not { "Tokenization failed: " -01 cat die } rep + } loop -- ] } /tokenize deff { dump + [ ] assembler .execute } /interpretToken deff { /input defv @@ -40,7 +44,7 @@ 4096 input .readstr cat _ "" streq not } { - { _ "([^\\n]*)\\n(.*)" regex } { ---10 tokenize |interpretToken each } loop + { _ "([^\\n]*)\\n(.*)" regex } { -102 -- tokenize |interpretToken each } loop } loop } /executeFile deff diff --git a/compiler/standard.ey b/compiler/standard.ey index 7c92e35..0d96431 100644 --- a/compiler/standard.ey +++ b/compiler/standard.ey @@ -1,7 +1,44 @@ +|defv "==" deff +|deff "=*" deff + { "}" | * { /f deff /x defv { x f } } quoted { } { * } ? * -} "}0" defq +} "}_" defq + +{ ==f _ ==a len ==l + l { + 0 a * + 1 l 1 sub range { a * f * } each + } { "fold on empty array" die } + ? * +} /fold deff + +{ |or fold } /any deff +{ |and fold } /all deff + +{ =*p { + [ -01 { _ p { } { -- } ? * } each ] +} } /engrep deff + +{ engrep * } /grep deff +{ -110 ; engrep |dom -20*1* } /indices deff + +{ =*p _ =*a len ==l + 1 neg ==r + + 0 { + _ l lt 1 neg r eq and + } { + _ a p { _ =r } { } ? * + 1 add + } loop -- + r +} /index deff + +{ + not { "Assertion failure" die } rep +} /assert deff # vim: syn=elymas |
