aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2013-01-23 01:56:25 +0100
committerDrahflow <drahflow@gmx.de>2013-01-23 01:56:25 +0100
commitd7fbde238c596c3f7cbc5471a0efb32481bdf6b8 (patch)
tree988353c9d4dcd64f9f57a93bea60a962f588e04e
parente5b6407246b3fd64014f92e80679274cb1a7bfde (diff)
Thinner scope handling when necessary
Functions without own scope don't unneccesary save the current scope. This makes < > possible. Also: dearray implemented
-rw-r--r--compiler/elymasAsmLib.ey454
l---------examples/working-compiler/arraycat.test1
l---------examples/working-compiler/concat.test1
l---------examples/working-compiler/each.test1
l---------examples/working-compiler/fib.test1
l---------examples/working-compiler/fold.test1
l---------examples/working-compiler/hash-set.test1
l---------examples/working-compiler/scope.test1
-rw-r--r--examples/working/each.ey4
-rw-r--r--examples/working/fold.ey8
-rw-r--r--examples/working/hash-set.ey8
11 files changed, 337 insertions, 144 deletions
diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey
index 171b3a1..2b11dcd 100644
--- a/compiler/elymasAsmLib.ey
+++ b/compiler/elymasAsmLib.ey
@@ -328,7 +328,6 @@
] /internalAllocateArray defv
> { defv }' allocateOffsetStruct
- # TODO: don't touch scope at all, if unscoping function
[
8 /r15 :subqImm8Reg
/r15 :popqMem
@@ -336,12 +335,11 @@
currentScope /rbx :movqImmReg
/rbx /rsi :movqMemReg
/rsi /r15 :movqRegMem
- ] _ /unscopingFunctionHeader defv [
8 /rdi :movqImmReg
internalAllocateScope /rax :movqImmReg
/rax :callqReg
/rax /rbx :movqRegMem
- ] cat /scopingFunctionHeader defv
+ ] /scopingFunctionHeader defv
[
/r15 /rcx :movqMemReg
@@ -351,7 +349,18 @@
/r15 :pushqMem
8 /r15 :addqImm8Reg
:retn
- ] /functionFooter defv
+ ] /scopingFunctionFooter defv
+
+ [
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
+ ] /unscopingFunctionHeader defv
+
+ [
+ /r15 :pushqMem
+ 8 /r15 :addqImm8Reg
+ :retn
+ ] /unscopingFunctionFooter defv
# elymas functions, stack based ABI
@@ -700,11 +709,13 @@
# 1 -> value to assign
# does not change the default activation mode
[
- /rbx :popqReg
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
currentScope /rdi :movqImmReg
/rdi /rdi :movqMemReg
- /rsi :popqReg
+ /rbx :popqReg
+ /rbx /rsi :movqRegReg
internalResolve /rax :movqImmReg
/rax :callqReg
@@ -717,12 +728,16 @@
errUnresolvedName /rdi :movqImmReg
internalDumpErrorString /rax :movqImmReg
/rax :callqReg
+ /rbx /rdi :movqRegReg
+ internalDumpErrorString /rax :movqImmReg
+ /rax :callqReg
:ud2
@found
/rcx :popqMem
- /rbx :pushqReg
+ /r15 :pushqMem
+ 8 /r15 :addqImm8Reg
:retn
] :labelResolve /ey= defv
@@ -747,18 +762,18 @@
:ud2
@normalFunction
+ # load scope
+ 8 /rdx /rcx :movqMemDisp8Reg
+ /rcx /rcx :testqRegReg
+ /unscoped :jzLbl8
+
# save current scope
currentScope /rax :movqImmReg
/rax /rsi :movqMemReg
8 /r15 :subqImm8Reg
/rsi /r15 :movqRegMem
-
# enter scope
- 8 /rdx /rcx :movqMemDisp8Reg
- /rcx /rcx :testqRegReg
- /unscoped :jzLbl8
/rcx /rax :movqRegMem
- @unscoped
# handle typed function
16 /rdx /rcx :movqMemDisp8Reg
@@ -768,9 +783,7 @@
24 /rdx /rax :movqMemDisp8Reg
8 /rax :addqImm8Reg
/rax :callqReg
- /done :jmpLbl8
- @done
/r15 /rcx :movqMemReg
currentScope /rax :movqImmReg
/rcx /rax :movqRegMem
@@ -779,6 +792,19 @@
8 /r15 :addqImm8Reg
:retn
+ @unscoped
+ 24 /rdx /rax :movqMemDisp8Reg
+ 8 /rax :addqImm8Reg
+ /rax :callqReg
+
+ /r15 :pushqMem
+ 8 /r15 :addqImm8Reg
+ :retn
+
+ @unscopedTyped
+ # TODO think about whether this should be allowed to happen
+ :ud2
+
@arrayFunction
# rdx == array on heap
/rbx :popqReg
@@ -1045,6 +1071,38 @@
:retn
] :labelResolve /eydom defv
+ # push array contents on stack
+ # 0 -> number of elements to push
+ # 1 -> array
+ # 0 ... <- array contents
+ [
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
+
+ /rcx :popqReg
+ 8 /rcx /rcx :movqMemDisp8Reg
+
+ /rax :popqReg
+
+ /rcx /rcx :testqRegReg
+ /empty :jzLbl8
+ 8 /rdi :movqImmReg
+
+ @loop
+ 1 /rdi /rax :pushqMemIndexScale
+ 8 /rdi :addqImm8Reg
+ /edi /rax :cmplRegMem
+ /noreset :jaLbl8
+ 8 /rdi :movqImmReg
+ @noreset
+ /loop :loopLbl8
+
+ @empty
+ /r15 :pushqMem
+ 8 /r15 :addqImm8Reg
+ :retn
+ ] :labelResolve /eydearray defv
+
# create an array containing a continuous range of ints
# 0 -> last element included in range
# 1 -> first element included in range
@@ -1124,7 +1182,8 @@
/rbx :popqReg
currentScope /rax :movqImmReg
/rax :pushqMem
- 16 /rax /rcx :movqMemDisp8Reg
+ /rax /rcx :movqMemReg
+ 16 /rcx /rcx :movqMemDisp8Reg
/rcx /rax :movqRegMem
/rbx :pushqReg
@@ -1266,10 +1325,11 @@
/done :jmpLbl8
@inactive
- currentQuoted /rax :movqImmReg
- /rax /rax :movqMemReg
- /rax /rax :testqRegReg
+ currentQuoted /rbx :movqImmReg
+ /rbx /rbx :movqMemReg
+ /rbx /rbx :testqRegReg
/constructQuotedResolve :jnzLbl8
+ /rax :pushqReg
@done
8 /r15 :addqImm8Reg
@@ -1294,7 +1354,7 @@
/rax :pushqReg
internalExecuteIdentifierUnquoted /rax :movqImmReg
/rax :callqReg
- ] functionFooter cat loadToRdi
+ ] unscopingFunctionFooter cat loadToRdi
allocateCodeFromEncodingBuffer
# rax == code block on heap
@@ -1347,7 +1407,7 @@
/rax :pushqReg
|ey* /rax :movqImmReg
/rax :callqReg
- ] functionFooter cat loadToRdi
+ ] unscopingFunctionFooter cat loadToRdi
allocateCodeFromEncodingBuffer
# rax == code block on heap
@@ -1574,6 +1634,125 @@
8 /r15 :addqImm8Reg
:retn
] :labelResolve /eyeach defv
+
+ # explicitely resolve a scope member
+ # 0 -> member name
+ # 1 -> scope
+ [
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
+
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem # store identifier
+
+ /rdi :popqReg # fetch scope
+ /r15 /rsi :movqMemReg
+ internalResolve /rax :movqImmReg
+ /rax :callqReg
+
+ /rax /rax :testqRegReg
+ /unresolved :jzLbl8
+ /rax :pushqReg
+
+ 0 /rdx :cmpqImm8Reg
+ /inactive :jzLbl8
+ 1 /rdx :cmpqImm8Reg
+ /active :jzLbl8
+
+ # TODO: "invalid activation mode"
+ :ud2
+
+ @unresolved
+ errUnresolvedName /rdi :movqImmReg
+ internalDumpErrorString /rax :movqImmReg
+ /rax :callqReg
+ /r15 /rdi :movqMemReg
+ internalDumpErrorString /rax :movqImmReg
+ /rax :callqReg
+ :ud2
+
+ @active
+ |ey* /rax :movqImmReg
+ /rax :callqReg
+
+ @inactive
+ @done
+ 8 /r15 :addqImm8Reg
+ /r15 :pushqMem
+ 8 /r15 :addqImm8Reg
+ :retn
+ ] :labelResolve /ey. defv
+
+ # explicitely resolve a scope member, but never execute
+ # 0 -> member name
+ # 1 -> scope
+ [
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
+
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem # store identifier
+
+ /rdi :popqReg # fetch scope
+ /r15 /rsi :movqMemReg
+ internalResolve /rax :movqImmReg
+ /rax :callqReg
+
+ /rax /rax :testqRegReg
+ /unresolved :jzLbl8
+ /rax :pushqReg
+
+ 8 /r15 :addqImm8Reg
+ /r15 :pushqMem
+ 8 /r15 :addqImm8Reg
+ :retn
+
+ @unresolved
+ errUnresolvedName /rdi :movqImmReg
+ internalDumpErrorString /rax :movqImmReg
+ /rax :callqReg
+ /r15 /rdi :movqMemReg
+ internalDumpErrorString /rax :movqImmReg
+ /rax :callqReg
+ :ud2
+ ] :labelResolve /ey.| defv
+
+ # enumerate scope keys
+ # 0 -> scope
+ # 0 <- array of keys
+ [
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
+
+ /rax :popqReg
+ 8 /rax /rax :movqMemDisp8Reg
+
+ 16 /rax /rsi :leaqMemDisp8Reg
+ /rsi :pushqReg
+ 8 /rax /rdi :movqMemDisp8Reg
+ 16 /rdi :subqImm8Reg
+ /rdi :pushqReg
+ /rdi :shrq1Reg
+ internalAllocateArray /rax :movqImmReg
+ /rax :callqReg
+
+ 8 /rax /rdi :leaqMemDisp8Reg
+ /rcx :popqReg
+ /rsi :popqReg
+ 4 /rcx :shrqImm8Reg
+ /empty :jzLbl8
+ @loop
+ :movsq
+ 8 /rsi :addqImm8Reg
+ /loop :loopLbl8
+ @empty
+
+ /rax :pushqReg
+
+ /r15 :pushqMem
+ 8 /r15 :addqImm8Reg
+ :retn
+ ] :labelResolve /eykeys defv
> _ ==globalFunctions2 { defv }' allocateOffsetStruct
<
@@ -1588,147 +1767,150 @@
] /ey{ defv
# quote construction, create function from begin marker onwards
- [
- 8 /r15 :subqImm8Reg
- /r15 :popqMem
+ { ==footer ==header
+ [
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
- currentQuoted /rcx :movqImmReg
- /rcx :decqMem
+ currentQuoted /rcx :movqImmReg
+ /rcx :decqMem
- QUOTEMARKER /rcx :movqImmReg
- /rcx :pushqReg
- /rsp /rdx :movqRegReg
- @backwardsSearch
- 8 /rdx :addqImm8Reg
- /rdx /rcx :cmpqMemReg
- /backwardsSearch :jneLbl8
+ QUOTEMARKER /rcx :movqImmReg
+ /rcx :pushqReg
+ /rsp /rdx :movqRegReg
+ @backwardsSearch
+ 8 /rdx :addqImm8Reg
+ /rdx /rcx :cmpqMemReg
+ /backwardsSearch :jneLbl8
- /rdx :pushqReg # store address of begin marker
+ /rdx :pushqReg # store address of begin marker
- :quoteEncodingBuffer /rdi :movqImmReg
- scopingFunctionHeader loadToRdi
+ :quoteEncodingBuffer /rdi :movqImmReg
+ header loadToRdi
- @search
- 8 /rdx :subqImm8Reg
- /rdx /rcx :cmpqMemReg
- /markerFound :jeLbl8
-
- /rdx /rsi :movqMemReg
- 7 /rsi /al :movbMemDisp8Reg
- %F0 /al :andbImmReg
- /immediateFound :jzLbl8
- %10 /al :cmpbImmReg
- /immediateFound :jzLbl8
- %50 /al :cmpbImmReg
- /functionFound :jzLbl8
- %70 /al :cmpbImmReg
- /arrayFound :jzLbl8
-
- # TODO: "invalid object during quote construction"
- :ud2
+ @search
+ 8 /rdx :subqImm8Reg
+ /rdx /rcx :cmpqMemReg
+ /markerFound :jeLbl8
- @immediateFound
- [ /rax :movqImmOOBReg ] _ len 2 eq assert
- 2 dearray 256 mul add
- /rdi :movwImmMem
- /rsi 2 /rdi :movqRegMemDisp8
- [ /rax :pushqReg ] _ len 1 eq assert
- 1 dearray
- 10 /rdi :movbImmMemDisp8
- 11 /rdi :addqImm8Reg
- /search :jmpLbl8
+ /rdx /rsi :movqMemReg
+ 7 /rsi /al :movbMemDisp8Reg
+ %F0 /al :andbImmReg
+ /immediateFound :jzLbl8
+ %10 /al :cmpbImmReg
+ /immediateFound :jzLbl8
+ %50 /al :cmpbImmReg
+ /functionFound :jzLbl8
+ %70 /al :cmpbImmReg
+ /arrayFound :jzLbl8
+
+ # TODO: "invalid object during quote construction"
+ :ud2
- @functionFound
- [ /rax :movqImmOOBReg ] _ len 2 eq assert
- 2 dearray 256 mul add
- /rdi :movwImmMem
- /rsi 2 /rdi :movqRegMemDisp8
- [ /rax :pushqReg ] _ len 1 eq assert
- 1 dearray
- 10 /rdi :movbImmMemDisp8
- 11 /rdi :addqImm8Reg
- [
- |ey* /rax :movqImmReg
- /rax :callqReg
- ] loadToRdi
- /search :jmpLbl8
+ @immediateFound
+ [ /rax :movqImmOOBReg ] _ len 2 eq assert
+ 2 dearray 256 mul add
+ /rdi :movwImmMem
+ /rsi 2 /rdi :movqRegMemDisp8
+ [ /rax :pushqReg ] _ len 1 eq assert
+ 1 dearray
+ 10 /rdi :movbImmMemDisp8
+ 11 /rdi :addqImm8Reg
+ /search :jmpLbl8
+
+ @functionFound
+ [ /rax :movqImmOOBReg ] _ len 2 eq assert
+ 2 dearray 256 mul add
+ /rdi :movwImmMem
+ /rsi 2 /rdi :movqRegMemDisp8
+ [ /rax :pushqReg ] _ len 1 eq assert
+ 1 dearray
+ 10 /rdi :movbImmMemDisp8
+ 11 /rdi :addqImm8Reg
+ [
+ |ey* /rax :movqImmReg
+ /rax :callqReg
+ ] loadToRdi
+ /search :jmpLbl8
- @arrayFound
- # FIXME allow macros to put byte arrays into quoted contexts and thereby generate assembly
- :ud2
- /search :jmpLbl8
+ @arrayFound
+ # FIXME allow macros to put byte arrays into quoted contexts and thereby generate assembly
+ :ud2
+ /search :jmpLbl8
- @markerFound
+ @markerFound
- functionFooter loadToRdi
- allocateCodeFromEncodingBuffer
+ footer loadToRdi
+ allocateCodeFromEncodingBuffer
- # rax == code block on heap
+ # rax == code block on heap
- currentQuoted /rcx :movqImmReg
- /rcx /rcx :movqMemReg
- /rcx /rcx :testqRegReg
- /quoted :jnzLbl8
+ currentQuoted /rcx :movqImmReg
+ /rcx /rcx :movqMemReg
+ /rcx /rcx :testqRegReg
+ /quoted :jnzLbl8
- # create function object
- /rax /rdi :movqRegReg
- currentScope /rax :movqImmReg
- /rax /rsi :movqMemReg
- /rdx /rdx :xorqRegReg
- internalAllocateFunction /rax :movqImmReg
- /rax :callqReg
+ # create function object
+ /rax /rdi :movqRegReg
+ currentScope /rax :movqImmReg
+ /rax /rsi :movqMemReg
+ /rdx /rdx :xorqRegReg
+ internalAllocateFunction /rax :movqImmReg
+ /rax :callqReg
- @done
- # rax == function object on heap
+ @done
+ # rax == function object on heap
- # store function instead of begin marker
- /rdx :popqReg
- /rax /rdx :movqRegMem
- /rdx /rsp :movqRegReg # and drop quoted stuff from stack
+ # store function instead of begin marker
+ /rdx :popqReg
+ /rax /rdx :movqRegMem
+ /rdx /rsp :movqRegReg # and drop quoted stuff from stack
- /r15 :pushqMem
- 8 /r15 :addqImm8Reg
- :retn
+ /r15 :pushqMem
+ 8 /r15 :addqImm8Reg
+ :retn
- @quoted
- # rax == (inner) code object on heap
+ @quoted
+ # rax == (inner) code object on heap
- # create function which
- # returns a function with the current scope captured
- :quoteEncodingBuffer /rdi :movqImmReg
- unscopingFunctionHeader loadToRdi
+ # create function which
+ # returns a function with the current scope captured
+ :quoteEncodingBuffer /rdi :movqImmReg
+ unscopingFunctionHeader loadToRdi
- # 1. load inner code block
- [ /rdi :movqImmOOBReg ] _ len 2 eq assert
- 2 dearray 256 mul add
- /rdi :movwImmMem
- /rax 2 /rdi :movqRegMemDisp8
- 10 /rdi :addqImm8Reg
+ # 1. load inner code block
+ [ /rdi :movqImmOOBReg ] _ len 2 eq assert
+ 2 dearray 256 mul add
+ /rdi :movwImmMem
+ /rax 2 /rdi :movqRegMemDisp8
+ 10 /rdi :addqImm8Reg
- [
- currentScope /rax :movqImmReg
- /rax /rsi :movqMemReg
+ [
+ currentScope /rax :movqImmReg
+ /rax /rsi :movqMemReg
+ /rdx /rdx :xorqRegReg
+ internalAllocateFunction /rax :movqImmReg
+ /rax :callqReg
+ /rax :pushqReg
+ ] unscopingFunctionFooter cat loadToRdi
+
+ allocateCodeFromEncodingBuffer
+
+ # rax == code object on heap
+
+ # create function object
+ /rax /rdi :movqRegReg
+ /rsi /rsi :xorqRegReg # non-capturing
/rdx /rdx :xorqRegReg
internalAllocateFunction /rax :movqImmReg
/rax :callqReg
- /rax :pushqReg
- ] functionFooter cat loadToRdi
-
- allocateCodeFromEncodingBuffer
- # rax == code object on heap
+ # rax == function object on heap
- # create function object
- /rax /rdi :movqRegReg
- /rsi /rsi :xorqRegReg # non-capturing
- /rdx /rdx :xorqRegReg
- internalAllocateFunction /rax :movqImmReg
- /rax :callqReg
-
- # rax == function object on heap
-
- /done :jmpLbl32
- ] :labelResolve /ey} defv
+ /done :jmpLbl32
+ ] :labelResolve
+ } _ scopingFunctionHeader scopingFunctionFooter -102* /ey} defv
+ unscopingFunctionHeader unscopingFunctionFooter -102* /ey}' defv
> _ ==globalMacros { defv }' allocateOffsetStruct
{ strToUTF8Bytes _ =*v len _ ==exactLength
diff --git a/examples/working-compiler/arraycat.test b/examples/working-compiler/arraycat.test
new file mode 120000
index 0000000..250dcdd
--- /dev/null
+++ b/examples/working-compiler/arraycat.test
@@ -0,0 +1 @@
+../working/arraycat.ey \ No newline at end of file
diff --git a/examples/working-compiler/concat.test b/examples/working-compiler/concat.test
new file mode 120000
index 0000000..b65356c
--- /dev/null
+++ b/examples/working-compiler/concat.test
@@ -0,0 +1 @@
+../working/concat.ey \ No newline at end of file
diff --git a/examples/working-compiler/each.test b/examples/working-compiler/each.test
new file mode 120000
index 0000000..95ed5d2
--- /dev/null
+++ b/examples/working-compiler/each.test
@@ -0,0 +1 @@
+../working/each.ey \ No newline at end of file
diff --git a/examples/working-compiler/fib.test b/examples/working-compiler/fib.test
new file mode 120000
index 0000000..f4d924e
--- /dev/null
+++ b/examples/working-compiler/fib.test
@@ -0,0 +1 @@
+../working/fib.ey \ No newline at end of file
diff --git a/examples/working-compiler/fold.test b/examples/working-compiler/fold.test
new file mode 120000
index 0000000..13cc7fd
--- /dev/null
+++ b/examples/working-compiler/fold.test
@@ -0,0 +1 @@
+../working/fold.ey \ No newline at end of file
diff --git a/examples/working-compiler/hash-set.test b/examples/working-compiler/hash-set.test
new file mode 120000
index 0000000..0efdd80
--- /dev/null
+++ b/examples/working-compiler/hash-set.test
@@ -0,0 +1 @@
+../working/hash-set.ey \ No newline at end of file
diff --git a/examples/working-compiler/scope.test b/examples/working-compiler/scope.test
new file mode 120000
index 0000000..3fc0fb0
--- /dev/null
+++ b/examples/working-compiler/scope.test
@@ -0,0 +1 @@
+../working/scope.ey \ No newline at end of file
diff --git a/examples/working/each.ey b/examples/working/each.ey
index 0e59bc9..54b0323 100644
--- a/examples/working/each.ey
+++ b/examples/working/each.ey
@@ -1 +1,3 @@
-[ 1 2 3 ] { =i i dump } each
+|defv "==" deff
+
+[ 1 2 3 ] { ==i i dump } each
diff --git a/examples/working/fold.ey b/examples/working/fold.ey
index 9ae19d5..d3b20ce 100644
--- a/examples/working/fold.ey
+++ b/examples/working/fold.ey
@@ -1,4 +1,6 @@
-{ =f =a a len =l
+|defv "==" deff
+
+{ ==f ==a a len ==l
l {
0 a *
1 l 1 sub range { a * f * } each
@@ -6,9 +8,9 @@
? *
} /fold deff
-{ =f _ len =l l dearray l 1 sub f rep } /foldshort deff
+{ ==f _ len ==l l dearray l 1 sub f rep } /foldshort deff
-{ =f { f fold } } /enfold deff
+{ ==f { f fold } } /enfold deff
[ 1 2 3 ]
_ |add fold dump
diff --git a/examples/working/hash-set.ey b/examples/working/hash-set.ey
index 495c27f..046e42b 100644
--- a/examples/working/hash-set.ey
+++ b/examples/working/hash-set.ey
@@ -1,4 +1,4 @@
-< { defv }' /put deff > =hashSet
+< { defv }' /put deff > /hashSet defv
1 /one hashSet .put
2 /two hashSet .put
@@ -8,12 +8,12 @@ hashSet .two dump
hashSet keys dump
{
- < { defv }' /put deff > =hashSetB
+ < { defv }' /put deff > /hashSetB defv
1 /one hashSetB .put
2 /two hashSetB .put
hashSetB .one dump
hashSetB .two dump
- hashSetB keys dump
-} *
+ hashSetB
+} * keys dump