aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2012-12-31 19:00:08 +0100
committerDrahflow <drahflow@gmx.de>2012-12-31 19:00:08 +0100
commitd7d307dc6563fe27bf43cab1e83ac21204fea6c6 (patch)
tree13a37937bbdb8a25c953183be0b8cf61e3acc6a9
parentac637b1cda03446a57ca6b1f20e5e63f1c8d7d0f (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.ey134
-rw-r--r--compiler/elymasGlobal.ey24
-rw-r--r--compiler/standard.ey39
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