diff options
| author | Drahflow <drahflow@gmx.de> | 2013-01-23 01:56:25 +0100 |
|---|---|---|
| committer | Drahflow <drahflow@gmx.de> | 2013-01-23 01:56:25 +0100 |
| commit | d7fbde238c596c3f7cbc5471a0efb32481bdf6b8 (patch) | |
| tree | 988353c9d4dcd64f9f57a93bea60a962f588e04e | |
| parent | e5b6407246b3fd64014f92e80679274cb1a7bfde (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.ey | 454 | ||||
| l--------- | examples/working-compiler/arraycat.test | 1 | ||||
| l--------- | examples/working-compiler/concat.test | 1 | ||||
| l--------- | examples/working-compiler/each.test | 1 | ||||
| l--------- | examples/working-compiler/fib.test | 1 | ||||
| l--------- | examples/working-compiler/fold.test | 1 | ||||
| l--------- | examples/working-compiler/hash-set.test | 1 | ||||
| l--------- | examples/working-compiler/scope.test | 1 | ||||
| -rw-r--r-- | examples/working/each.ey | 4 | ||||
| -rw-r--r-- | examples/working/fold.ey | 8 | ||||
| -rw-r--r-- | examples/working/hash-set.ey | 8 |
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 |
