diff --git a/Examples/Benchmarks/All.som b/Examples/Benchmarks/All.som new file mode 100644 index 0000000..8bf9395 --- /dev/null +++ b/Examples/Benchmarks/All.som @@ -0,0 +1,40 @@ +" + +$Id: All.som 286 2008-05-09 22:38:14Z daniel.richter $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +All = ( + + run = ( + | total | + total := 0. + + Fibonacci, Dispatch, Bounce, Loop, Permute, Queens, List, Recurse, + Storage, Sieve, BubbleSort, QuickSort, Sum, Towers, TreeSort, + IntegerLoop + do: [ :benchmark | total := total + benchmark new run ]. + + ('All tests completed (' + total + ' ms)') println. + ) + +) diff --git a/Examples/Benchmarks/Ball.som b/Examples/Benchmarks/Ball.som new file mode 100644 index 0000000..29eaa17 --- /dev/null +++ b/Examples/Benchmarks/Ball.som @@ -0,0 +1,59 @@ +" + +$Id: Ball.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Ball = ( + + | x y xVel yVel | + + bounce = ( + | xLimit yLimit bounced | + xLimit := yLimit := 500. + bounced := false. + + x := x + xVel. + y := y + yVel. + (x > xLimit) + ifTrue: [ x := xLimit. xVel := 0 - xVel abs. bounced := true ]. + (x < 0) + ifTrue: [ x := 0. xVel := xVel abs. bounced := true ]. + (y > yLimit) + ifTrue: [ y := yLimit. yVel := 0 - yVel abs. bounced := true ]. + (y < 0) + ifTrue: [ y := 0. yVel := yVel abs. bounced := true ]. + ^bounced + ) + + initialize = ( + x := Random next % 500. + y := Random next % 500. + xVel := (Random next % 300) - 150. + yVel := (Random next % 300) - 150. + ) + + ----------------- + + new = ( ^super new initialize ) + +) diff --git a/Examples/Benchmarks/Benchmark.som b/Examples/Benchmarks/Benchmark.som new file mode 100644 index 0000000..0cf8aac --- /dev/null +++ b/Examples/Benchmarks/Benchmark.som @@ -0,0 +1,50 @@ +" + +$Id: Benchmark.som 526 2008-05-28 20:58:38Z daniel.richter $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Benchmark = ( + + run = ( + | startTime elapsedTime averageTime iterations | + + (('Starting ' + (self name)) + ' benchmark ... ') println. + + iterations := elapsedTime := 0. + startTime := system time. + + [ elapsedTime < 2000 ] + whileTrue: [ + self benchmark. + iterations := iterations + 1. + elapsedTime := system time - startTime. ]. + + averageTime := elapsedTime / iterations. + (' Completed (' + averageTime + ' ms)') println. '' println. + ^averageTime + ) + + benchmark = ( self subclassResponsibility ) + name = ( ^self class name asString ) + +) diff --git a/Examples/Benchmarks/Bounce.som b/Examples/Benchmarks/Bounce.som new file mode 100644 index 0000000..da91acd --- /dev/null +++ b/Examples/Benchmarks/Bounce.som @@ -0,0 +1,46 @@ +" + +$Id: Bounce.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Bounce = Benchmark ( + + benchmark = ( + | ballCount balls bounces | + + Random initialize. + + ballCount := 100. + bounces := 0. + balls := Array new: ballCount withAll: [ Ball new ]. + + 1 to: 50 do: [ :i | + balls do: [ :ball | + (ball bounce) ifTrue: [ bounces := bounces + 1 ] ] ]. + + (bounces = 1331) + ifFalse: [ + self error: 'Wrong result: ' + bounces + ' should be: 1331' ] + ) + +) diff --git a/Examples/Benchmarks/BubbleSort.som b/Examples/Benchmarks/BubbleSort.som new file mode 100644 index 0000000..cc394f5 --- /dev/null +++ b/Examples/Benchmarks/BubbleSort.som @@ -0,0 +1,46 @@ +" + +$Id: BubbleSort.som 223 2008-04-21 11:48:41Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +BubbleSort = Sort ( + + sort: array = ( + | top | + + "array length - 1 downTo: 0 do: [ :i | + 0 to: i - 1 do: [ :j |" + array length downTo: 1 do: [ :i | + 1 to: i - 1 do: [ :j | + | current next | + current := array at: j. + next := array at: j + 1. + (current > next) + ifTrue: [ + array at: j put: next. + array at: j + 1 put: current ] ] ] + ) + + dataSize = ( ^130 ) + +) diff --git a/Examples/Benchmarks/Dispatch.som b/Examples/Benchmarks/Dispatch.som new file mode 100644 index 0000000..dbbd54f --- /dev/null +++ b/Examples/Benchmarks/Dispatch.som @@ -0,0 +1,34 @@ +" + +$Id: Dispatch.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Dispatch = Benchmark ( + + benchmark = ( + 1 to: 20000 do: [ :i | self method: i ] + ) + + method: argument = ( ^argument ) + +) diff --git a/Examples/Benchmarks/Fibonacci.som b/Examples/Benchmarks/Fibonacci.som new file mode 100644 index 0000000..25ee711 --- /dev/null +++ b/Examples/Benchmarks/Fibonacci.som @@ -0,0 +1,41 @@ +" + +$Id: Fibonacci.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Fibonacci = Benchmark ( + + benchmark = ( | result | + result := self fibonacci: 20. + (result = 10946) + ifFalse: [ + self error: 'Wrong result: ' + result + ' should be: 10946' ] + ) + + fibonacci: n = ( + ^(n <= 1) + ifTrue: 1 + ifFalse: [ (self fibonacci: (n - 1)) + (self fibonacci: (n - 2)) ] + ) + +) diff --git a/Examples/Benchmarks/IntegerLoop.som b/Examples/Benchmarks/IntegerLoop.som new file mode 100644 index 0000000..84e0c0c --- /dev/null +++ b/Examples/Benchmarks/IntegerLoop.som @@ -0,0 +1,34 @@ +" + +$Id: List.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +IntegerLoop = Benchmark ( + + benchmark = ( | bounds | + + bounds := 20000. + + bounds negated to: bounds by: 1 do: [:value | |a| a := value-value]. + ) +) diff --git a/Examples/Benchmarks/List.som b/Examples/Benchmarks/List.som new file mode 100644 index 0000000..9fe082a --- /dev/null +++ b/Examples/Benchmarks/List.som @@ -0,0 +1,70 @@ +" + +$Id: List.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +List = Benchmark ( + + benchmark = ( | result | + result := self + taklWithX: (self makeList: 15) + withY: (self makeList: 10) + withZ: (self makeList: 6). + (result length = 10) + ifFalse: [ + self error: + 'Wrong result: ' + result length asString + ' should be: 10' ]. + ) + + makeList: length = ( + (length = 0) + ifTrue: [ ^nil ] + ifFalse: [ + ^(ListElement new: length) + next: (self makeList: (length - 1)) ] + ) + + isShorter: x than: y = ( + | xTail yTail | + + xTail := x. yTail := y. + [ yTail isNil ] + whileFalse: [ + xTail isNil ifTrue: [ ^true ]. + xTail := xTail next. + yTail := yTail next ]. + + ^false + ) + + taklWithX: x withY: y withZ: z = ( + (self isShorter: y than: x) + ifTrue: [ + ^(self + taklWithX: (self taklWithX: x next withY: y withZ: z) + withY: (self taklWithX: y next withY: z withZ: x) + withZ: (self taklWithX: z next withY: x withZ: y)) ] + ifFalse: [ ^z ]. + ) + +) diff --git a/Examples/Benchmarks/ListElement.som b/Examples/Benchmarks/ListElement.som new file mode 100644 index 0000000..61c1997 --- /dev/null +++ b/Examples/Benchmarks/ListElement.som @@ -0,0 +1,43 @@ +" + +$Id: ListElement.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +ListElement = ( + + | val next | + + length = ( next isNil ifTrue: [ ^1 ] ifFalse: [ ^(1 + next length) ] ) + + val = ( ^val ) + val: n = ( val := n ) + + next = ( ^next ) + next: element = ( next := element ) + + ------------------ + + new: n = ( ^super new val: n ) + +) + diff --git a/Examples/Benchmarks/Loop.som b/Examples/Benchmarks/Loop.som new file mode 100644 index 0000000..f94a1b3 --- /dev/null +++ b/Examples/Benchmarks/Loop.som @@ -0,0 +1,37 @@ +" + +$Id: Loop.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Loop = Benchmark ( + + benchmark = ( + | sum | + sum := 0. + 1 to: 200 do: [ :i | 1 to: 100 do: [ :j | sum := sum + 1 ] ]. + (sum = 20000) + ifFalse: [ + self error: 'Wrong result: ' + sum + ' should be: 20000' ] + ) + +) diff --git a/Examples/Benchmarks/Permute.som b/Examples/Benchmarks/Permute.som new file mode 100644 index 0000000..adc2fc6 --- /dev/null +++ b/Examples/Benchmarks/Permute.som @@ -0,0 +1,57 @@ +" + +$Id: Permute.som 223 2008-04-21 11:48:41Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Permute = Benchmark ( + + | count v | + + benchmark = ( + count := 0. + v := Array new: 7. + self permute: 6. + (count = 8660) + ifFalse: [ + self error: 'Wrong result: ' + count + ' should be: 8660' ] + ) + + permute: n = ( + count := count + 1. + (n <> 0) + ifTrue: [ + self permute: n - 1. + n downTo: 1 do: [ :i | + self swap: n with: i. + self permute: n - 1. + self swap: n with: i ] ] + ) + + swap: i with: j = ( + | tmp | + tmp := v at: i. + v at: i put: (v at: j). + v at: j put: tmp + ) + +) diff --git a/Examples/Benchmarks/Queens.som b/Examples/Benchmarks/Queens.som new file mode 100644 index 0000000..35a0f42 --- /dev/null +++ b/Examples/Benchmarks/Queens.som @@ -0,0 +1,65 @@ +" + +$Id: Queens.som 223 2008-04-21 11:48:41Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Queens = Benchmark ( + + | freeMajs freeRows freeMins queenRows | + + benchmark = ( + 1 to: 10 do: [ :i | self queens ] + ) + + queens = ( + freeRows := Array new: 8 withAll: true. + freeMajs := Array new: 16 withAll: true. + freeMins := Array new: 16 withAll: true. + queenRows := Array new: 8 withAll: -1. + (self placeQueen: 1) ifFalse: [ self error: 'Wrong result' ] + ) + + placeQueen: c = ( + 1 to: 8 do: [ :r | + (self row: r column: c) + ifTrue: [ + queenRows at: r put: c. + self row: r column: c put: false. + (c = 8) ifTrue: [ ^true ]. + (self placeQueen: c + 1) ifTrue: [ ^true ]. + self row: r column: c put: true ] ]. + ^false + ) + + row: r column: c = ( + ^(freeRows at: r) && (freeMajs at: c + r) && (freeMins at: c - r + 8) + ) + + row: r column: c put: v = ( + freeRows at: r put: v. + freeMajs at: c + r put: v. + freeMins at: c - r + 8 put: v. + ) + +) + diff --git a/Examples/Benchmarks/QuickSort.som b/Examples/Benchmarks/QuickSort.som new file mode 100644 index 0000000..d401b98 --- /dev/null +++ b/Examples/Benchmarks/QuickSort.som @@ -0,0 +1,57 @@ +" + +$Id: QuickSort.som 223 2008-04-21 11:48:41Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +QuickSort = Sort ( + + sort: array = ( + self sort: array low: 1 high: self dataSize + ) + + sort: array low: low high: high = ( + | pivot i j | + + pivot := array at: (low + high) / 2. + i := low. + j := high. + [ i <= j ] + whileTrue: [ + [ (array at: i) < pivot ] whileTrue: [ i := i + 1 ]. + [ pivot < (array at: j) ] whileTrue: [ j := j - 1 ]. + ( i <= j ) + ifTrue: [ + | tmp | + tmp := array at: i. + array at: i put: (array at: j). + array at: j put: tmp. + i := i + 1. + j := j - 1. ] ]. + + (low < j) ifTrue: [ self sort: array low: low high: j ]. + (i < high) ifTrue: [ self sort: array low: i high: high ] + ) + + dataSize = ( ^800 ) + +) diff --git a/Examples/Benchmarks/Random.som b/Examples/Benchmarks/Random.som new file mode 100644 index 0000000..54cc597 --- /dev/null +++ b/Examples/Benchmarks/Random.som @@ -0,0 +1,68 @@ +" + +$Id: Random.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Random = Benchmark ( + + | seed | + + initialize = ( + seed := 74755 + ) + + next = ( + seed := ((seed * 1309) + 13849) & 65535. + ^seed + ) + + run = ( + | fail | + 'Testing random number generator ... ' print. + fail := [ 'FAILED:' println. ^nil ]. + (self next <> 22896) ifTrue: fail. + (self next <> 34761) ifTrue: fail. + (self next <> 34014) ifTrue: fail. + (self next <> 39231) ifTrue: fail. + (self next <> 52540) ifTrue: fail. + (self next <> 41445) ifTrue: fail. + (self next <> 1546) ifTrue: fail. + (self next <> 5947) ifTrue: fail. + (self next <> 65224) ifTrue: fail. + 'PASSED' println + ) + + ------------------- + + | random | + + new = ( ^super new initialize ) + next = ( ^self random next ) + initialize = ( ^self random initialize ) + + random = ( + (random <> nil) ifTrue: [ ^random ]. + ^random := Random new + ) + +) \ No newline at end of file diff --git a/Examples/Benchmarks/Recurse.som b/Examples/Benchmarks/Recurse.som new file mode 100644 index 0000000..0ee0e79 --- /dev/null +++ b/Examples/Benchmarks/Recurse.som @@ -0,0 +1,36 @@ +" + +$Id: Recurse.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Recurse = Benchmark ( + + benchmark = ( + self recurse: 13 + ) + + recurse: n = ( + (n > 0) ifTrue: [ self recurse: n - 1. self recurse: n - 1 ] + ) + +) \ No newline at end of file diff --git a/Examples/Benchmarks/Sieve.som b/Examples/Benchmarks/Sieve.som new file mode 100644 index 0000000..910e2b0 --- /dev/null +++ b/Examples/Benchmarks/Sieve.som @@ -0,0 +1,53 @@ +" + +$Id: Sieve.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Sieve = Benchmark ( + + benchmark = ( + | flags result | + flags := Array new: 5000. + result := self sieve: flags size: 5000. + (result = 669) + ifFalse: [ + self error: 'Wrong result: ' + result + ' should be: 669' ] + ) + + sieve: flags size: size = ( + | primeCount | + primeCount := 0. + flags putAll: true. + 2 to: size do: [ :i | + (flags at: i - 1) + ifTrue: [ + | k | + primeCount := primeCount + 1. + k := i + i. + [ k <= size ] + whileTrue: [ + flags at: k - 1 put: false. k := k + i ]. ] ]. + ^primeCount + ) + +) diff --git a/Examples/Benchmarks/Sort.som b/Examples/Benchmarks/Sort.som new file mode 100644 index 0000000..c3d45cd --- /dev/null +++ b/Examples/Benchmarks/Sort.som @@ -0,0 +1,59 @@ +" + +$Id: Sort.som 223 2008-04-21 11:48:41Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Sort = Benchmark ( + + | smallest largest | + + benchmark = ( + | array | + array := self randomArray: self dataSize. + self sort: array. + self checkArray: array + ) + + sort: array = ( self subclassResponsibility ) + + checkArray: array = ( + ((array at: 1) <> smallest) + || ((array at: (array length)) <> largest) + ifTrue: [ self error: 'Array is not sorted' ]. + 3 to: (array length) do: [ :i | + (array at: i - 1) > (array at: i) + ifTrue: [ self error: 'Array is not sorted' ]. ] + ) + + randomArray: size = ( + | array | + Random initialize. + array := Array new: size withAll: [ Random next ]. + smallest := largest := array at: 1. + array do: [ :elm | + (elm > largest) ifTrue: [ largest := elm ]. + (elm < smallest) ifTrue: [ smallest := elm ]. ]. + ^array + ) + +) diff --git a/Examples/Benchmarks/Storage.som b/Examples/Benchmarks/Storage.som new file mode 100644 index 0000000..519db0b --- /dev/null +++ b/Examples/Benchmarks/Storage.som @@ -0,0 +1,47 @@ +" + +$Id: Storage.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Storage = Benchmark ( + + | count | + + benchmark = ( + Random initialize. + count := 0. + self buildTreeDepth: 7. + (count = 5461) + ifFalse: [ + self error: 'Wrong result: ' + count + ' should be: 5461' ] + ) + + buildTreeDepth: depth = ( + count := count + 1. + ^(depth = 1) + ifTrue: [ Array new: Random next % 10 + 1 ] + ifFalse: [ + Array new: 4 withAll: [ self buildTreeDepth: depth - 1 ] ] + ) + +) diff --git a/Examples/Benchmarks/Sum.som b/Examples/Benchmarks/Sum.som new file mode 100644 index 0000000..85c23fc --- /dev/null +++ b/Examples/Benchmarks/Sum.som @@ -0,0 +1,42 @@ +" + +$Id: Sum.som 515 2008-05-28 15:18:49Z robert.timm $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Sum = Benchmark ( + + benchmark = ( + | result | + 1 to: 2 do: [ :i | result := self sumFrom: 1 to: 10000 ]. + (result = 50005000) + ifFalse: [ + self error: 'Wrong result: ' + result + ' should be: 50005000' ] + ) + + sumFrom: start to: end = ( + | sum | + sum := 0. + start to: end do: [ :i | sum := sum + i ]. + ^sum + ) +) diff --git a/Examples/Benchmarks/Towers.som b/Examples/Benchmarks/Towers.som new file mode 100644 index 0000000..6ceb23f --- /dev/null +++ b/Examples/Benchmarks/Towers.som @@ -0,0 +1,87 @@ +" + +$Id: Towers.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +"Mmm... Hanoi..." + +Towers = Benchmark ( + + | piles movesdone | + + pushDisk: disk onPile: pile = ( + | top | + + top := piles at: pile. + (top isNil not) && [ disk size >= top size ] + ifTrue: [ self error: 'Cannot put a big disk on a smaller one' ]. + + disk next: top. + piles at: pile put: disk. + ) + + popDiskFrom: pile = ( + | top | + + top := piles at: pile. + top isNil + ifTrue: [ + self error: 'Attempting to remove a disk from an empty pile' ]. + + piles at: pile put: top next. + top next: nil. + ^top + ) + + moveTopDiskFrom: fromPile to: toPile = ( + self pushDisk: (self popDiskFrom: fromPile) onPile: toPile. + movesdone := movesdone + 1. + ) + + buildTowerAt: pile disks: disks = ( + disks downTo: 0 do: [ :i | + self pushDisk: (TowersDisk new: i) onPile: pile ] + ) + + move: disks disksFrom: fromPile to: toPile = ( + disks = 1 + ifTrue: [ self moveTopDiskFrom: fromPile to: toPile ] + ifFalse: [ | otherPile | + otherPile := (6 - fromPile) - toPile. + self move: disks - 1 disksFrom: fromPile to: otherPile. + self moveTopDiskFrom: fromPile to: toPile. + self move: disks - 1 disksFrom: otherPile to: toPile. ] + ) + + benchmark = ( + piles := Array new: 4. + self buildTowerAt: 1 disks: 13. + movesdone := 0. + self move: 13 disksFrom: 1 to: 2. + movesdone = 8191 + ifFalse: [ + self error: + 'Error in result: ' + movesdone + ' should be: 8191' ]. + ) + +) diff --git a/Examples/Benchmarks/TowersDisk.som b/Examples/Benchmarks/TowersDisk.som new file mode 100644 index 0000000..43e106a --- /dev/null +++ b/Examples/Benchmarks/TowersDisk.som @@ -0,0 +1,39 @@ +" + +$Id: TowersDisk.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +TowersDisk = ( + + | size next | + + size = ( ^size ) + size: value = ( size := value ) + next = ( ^next ) + next: value = ( next := value ) + + ----------------------------------- + + new: value = ( ^super new size: value ) + +) diff --git a/Examples/Benchmarks/TreeNode.som b/Examples/Benchmarks/TreeNode.som new file mode 100644 index 0000000..2f43aa6 --- /dev/null +++ b/Examples/Benchmarks/TreeNode.som @@ -0,0 +1,54 @@ +" + +$Id: TreeNode.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +TreeNode = ( + + | left right value | + + value = ( ^value ) + value: v = ( value := v ) + + check = ( + ^(left isNil || [ (left value < value) && left check ]) && + (right isNil || [ (right value >= value) && right check ]) + ) + + insert: n = ( + (n < value) + ifTrue: [ + left isNil + ifTrue: [ left := TreeNode new: n ] + ifFalse: [ left insert: n ] ] + ifFalse: [ + right isNil + ifTrue: [ right := TreeNode new: n ] + ifFalse: [ right insert: n ] ]. + ) + + ------------------------- + + new: value = ( ^super new value: value ) + +) diff --git a/Examples/Benchmarks/TreeSort.som b/Examples/Benchmarks/TreeSort.som new file mode 100644 index 0000000..11e01f3 --- /dev/null +++ b/Examples/Benchmarks/TreeSort.som @@ -0,0 +1,39 @@ +" + +$Id: TreeSort.som 223 2008-04-21 11:48:41Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +TreeSort = Sort ( + + benchmark = ( + | array tree | + + array := self randomArray: 1000. + array doIndexes: [ :i | + (i = 1) + ifTrue: [ tree := TreeNode new: (array at: i) ] + ifFalse: [ tree insert: (array at: i) ] ]. + tree check ifFalse: [ self error: 'Invalid result, tree not sorted' ]. + ) + +) diff --git a/Examples/Echo/Echo.som b/Examples/Echo/Echo.som new file mode 100644 index 0000000..4a66837 --- /dev/null +++ b/Examples/Echo/Echo.som @@ -0,0 +1,33 @@ +" + +$Id: Echo.som 226 2008-04-21 12:45:01Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Echo = ( + + run: args = ( + args from: 2 to: args length do: [ :arg | arg print. ' ' print ]. + '' println. + ) + +) diff --git a/Examples/Hello/Hello.som b/Examples/Hello/Hello.som new file mode 100644 index 0000000..256269e --- /dev/null +++ b/Examples/Hello/Hello.som @@ -0,0 +1,31 @@ +" + +$Id: Hello.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Hello = ( + + "The 'run' method is called when initializing the system" + run = ('Hello, World from SmallTalk(tm)' println ) + +) diff --git a/Examples/Snake/Apple.som b/Examples/Snake/Apple.som new file mode 100644 index 0000000..c839493 --- /dev/null +++ b/Examples/Snake/Apple.som @@ -0,0 +1,26 @@ +" + +$Id: Apple.som 191 2008-04-10 18:15:47Z michael.haupt $ + +Copyright (c) 2001-2008 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Apple = Element () diff --git a/Examples/Snake/Board.som b/Examples/Snake/Board.som new file mode 100644 index 0000000..e99b3d1 --- /dev/null +++ b/Examples/Snake/Board.som @@ -0,0 +1,118 @@ +" + +$Id: Board.som 426 2008-05-22 08:22:07Z stefan.marr $ + +Copyright (c) 2001-2008 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Board = ( + | view width height board | + + width = ( ^width ) + width: val = ( width := val. ) + + height = ( ^height ) + height: val = ( height := val ) + + board = ( ^board ) + board: val = ( board := val ) + + view = ( ^view ) + + addApple = ( + | added x y newApple | + added := false. + + [ added ] whileFalse: [ + x := 1 atRandom % width. "$x = rand(0, $this->width - 1);" + y := 1 atRandom % height. + + x := x + 1. + y := y + 1. + + (self board at: x) isNil ifTrue: [ + self board at: x put: (Array new: height). + ]. + + ((self board at: x) at: y) isNil ifTrue: [ + newApple := Apple newWithX: x Y: y. + (self board at: x) at: y put: newApple. + added := true. + view isNil ifFalse: [ + view addApple: newApple. + ]. + ] + ] + ) + + view: value = ( + view := value. + value board: board. + value updateCompletely. + ) + + isAppleAtX: x Y: y = ( + ((board at: x) isNil) ifFalse: [ + ((board at: x) at: y) isNil ifFalse: [ + ^((board at: x) at: y) class == Apple + ] + ]. + ^false + ) + + isSnakeAtX: x Y: y = ( + ((board at: x) isNil) ifFalse: [ + ((board at: x) at: y) isNil ifFalse: [ + ^((board at: x) at: y) class == SnakeElement + ] + ]. + ^false + ) + + remove: element = ( + (self board at: (element x)) at: (element y) put: nil. + self view remove: element + ) + + add: element = ( + (self board at: element x) isNil ifTrue: [ + self board at: (element x) put: (Array new: height). + ]. + (self board at: (element x)) at: (element y) put: element. + view add: element + ) + + ---- + + newWithWidth: width height: height numberOfApples: numberOfApples = ( + | newBoard | + newBoard := Board new. + newBoard board: (Array new: width). + newBoard width: width. + newBoard height: height. + + [numberOfApples >= 0] whileTrue: [ + newBoard addApple. + numberOfApples := numberOfApples - 1. + ]. + ^newBoard + ) +) diff --git a/Examples/Snake/BoardView.som b/Examples/Snake/BoardView.som new file mode 100644 index 0000000..08072bd --- /dev/null +++ b/Examples/Snake/BoardView.som @@ -0,0 +1,90 @@ +" + +$Id: BoardView.som 426 2008-05-22 08:22:07Z stefan.marr $ + +Copyright (c) 2001-2008 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +BoardView = ( + | board width height | + + board: value = ( board := value ) + width: value = ( width := value ) + height: value = ( height := value ) + + updateCompletely = ( + board do: [ :y | + y isNil ifFalse: [ + y do: [ :apple | + apple isNil ifFalse: [ + Terminal cursorToX: (apple x) Y: (apple y). + Terminal put: 'o' + ] + ] + ] + ] + ) + + remove: snakeElement = ( + Terminal cursorToX: snakeElement x + 1 Y: snakeElement y + 1. + Terminal put: ' ' + ) + + add: snakeElement = ( + Terminal cursorToX: snakeElement x + 1 Y: snakeElement y + 1. + Terminal put: '#' + ) + + addApple: apple = ( + Terminal cursorToX: apple x + 1 Y: apple y + 1. + Terminal put: 'o' + ) + + drawBoarder = ( + Terminal cursorToX: 1 Y: 1. + Terminal put: '/'. + width timesRepeat: [ Terminal put: '-' ]. + Terminal put: '\'. + + 1 to: height do: [ :i | + Terminal cursorToX: 1 Y: i + 1. + Terminal put: '|'. + Terminal cursorToX: (width + 2) Y: i + 1. + Terminal put: '|' + ]. + + Terminal cursorToX: 1 Y: height + 2. + Terminal put: '\'. + width timesRepeat: [ Terminal put: '-' ]. + Terminal put: '/'. + ) + + ---- + + new: board = ( + | newBoardView | + newBoardView := BoardView new. + board view: newBoardView. + newBoardView width: board width. + newBoardView height: board height. + ^newBoardView + ) +) diff --git a/Examples/Snake/Core.cpp b/Examples/Snake/Core.cpp new file mode 100644 index 0000000..7b3fa3a --- /dev/null +++ b/Examples/Snake/Core.cpp @@ -0,0 +1,47 @@ +#include + +//#include "../misc/defs.h" +//#include "../vmobjects/VMObject.h" +#include "../../vmobjects/PrimitiveRoutine.h" + +#include "Terminal.h" + +#include "../../primitivesCore/Routine.h" +#include "../../primitivesCore/PrimitiveContainer.h" +#include "../../primitivesCore/PrimitiveLoader.h" + +static PrimitiveLoader* loader = NULL; +//map primitiveObjects; +//"Constructor" +static bool initialized = false; +extern "C" void setup() { + if (!loader) { + //Initialize loader + loader = new PrimitiveLoader(); + loader->AddPrimitiveObject("Terminal", + static_cast(new Terminal())); +} + +extern "C" bool supportsClass(const char* name) { + //if (!loader) setup(); + return loader->SupportsClass(name); +} + + + +extern "C" void tearDown() { + //primitiveClasses.clear(); + if (loader) delete loader; + //if (primitiveObjects) delete primitiveObjects; +} + +extern "C" PrimitiveRoutine* create(const pString& cname, const pString& fname) { + +#ifdef __DEBUG + cout << "Loading PrimitiveContainer: " << cname << "::" << fname << endl; +#endif + //if (!loader) setup(); + + return loader->GetPrimitiveRoutine(cname, fname); +} + diff --git a/Examples/Snake/Element.som b/Examples/Snake/Element.som new file mode 100644 index 0000000..87033d2 --- /dev/null +++ b/Examples/Snake/Element.som @@ -0,0 +1,43 @@ +" + +$Id: Element.som 191 2008-04-10 18:15:47Z michael.haupt $ + +Copyright (c) 2001-2008 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Element = ( + | x y | + + x = ( ^x ) + x: val = ( x := val ) + + y = ( ^y ) + y: val = ( y := val ) + + ---- + newWithX: x Y: y = ( + | newElement | + newElement := self new. + newElement x: x. + newElement y: y. + ^newElement. + ) +) diff --git a/Examples/Snake/Main.som b/Examples/Snake/Main.som new file mode 100644 index 0000000..9c82f13 --- /dev/null +++ b/Examples/Snake/Main.som @@ -0,0 +1,83 @@ +" + +$Id: Main.som 191 2008-04-10 18:15:47Z michael.haupt $ + +Copyright (c) 2001-2008 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Main = ( + run = ( + | board view chr snake dir continue | + Terminal init. + Terminal clear. + dir := Terminal KEY_UP. + + board := Board newWithWidth: 10 height: 10 numberOfApples: 5. + view := BoardView new: board. + view drawBoarder. + + snake := Snake newWithX: 5 Y: 5 andBoard: board. + continue := true. + [ continue ] whileTrue: [ + chr := Terminal get. + ((Terminal KEY_UP = chr) + || ((Terminal KEY_DOWN) = chr) + || ((Terminal KEY_LEFT) = chr) + || ((Terminal KEY_RIGHT) = chr)) ifTrue: [ dir := chr ]. + Terminal sleepFor: 250. + + "Terminal cursorToX: 15 Y: 15." + (Terminal KEY_UP = dir) ifTrue: [ continue := snake moveUp ]. + (Terminal KEY_DOWN = dir) ifTrue: [ continue := snake moveDown ]. + (Terminal KEY_LEFT = dir) ifTrue: [ continue := snake moveLeft ]. + (Terminal KEY_RIGHT = dir) ifTrue: [ continue := snake moveRight ]. + '' println. + ]. + + 'GAME OVER' println. + Terminal uninit. + ) +) + +" + +while (true) { + $i = 4; + while ($i > 0) { + $key = Terminal::get(0); + if (in_array($key, array(Terminal::KEY_UP, Terminal::KEY_DOWN, Terminal::KEY_LEFT, Terminal::KEY_RIGHT))) { + $dir = $key; + } + usleep(100000); + $i--; + } + + + if (!$result) { + Terminal::cursorTo(5, 15); + Terminal::put('GAME OVER'); + sleep(5); + return; + } +} + +Terminal::clear(); +" diff --git a/Examples/Snake/Makefile b/Examples/Snake/Makefile new file mode 100644 index 0000000..e1c0eb4 --- /dev/null +++ b/Examples/Snake/Makefile @@ -0,0 +1,50 @@ +#!/usr/bin/env make + +TARGET =Terminal + + +################ ONLY CHANGE STUFF BELOW IF YOU REALLY HAVE ################### + + +CC =g++ +CFLAGS =-Wno-endif-labels -O2 $(DBG_FLAGS) $(INCLUDES) +LDFLAGS =-enable-auto-import $(LIBRARIES) + +INSTALL =install + +############ global stuff -- overridden by ../Makefile + +ROOT_DIR ?= $(PWD)/../.. +BUILD_DIR ?= $(ROOT_DIR)/build +SRC_DIR ?= $(ROOT_DIR)/src + +ST_DIR ?= $(ROOT_DIR)/Smalltalk +EX_DIR ?= $(ROOT_DIR)/Examples +TEST_DIR ?= $(ROOT_DIR)/TestSuite + +############# include path + +INCLUDES =-I$(SRC_DIR) +LIBRARIES =-L$(ROOT_DIR) + +ifneq ($(OS),) +# only Windows has OS predefined. + LIBS =-lm -l../../CPPSOM -l../../PrimitiveCore +endif + +all: $(TARGET).csp + +debug : DBG_FLAGS=-DDEBUG -g +debug: all + +profiling : DBG_FLAGS=-g -pg +profiling : LDFLAGS+=-pg +profiling: all + +$(TARGET).csp: + $(CC) $(CFLAGS) $(LDFLAGS) -shared -g \ + $(PWD)/$(TARGET).cpp -o $(TARGET).csp $(LIBS) + +clean: + rm -Rf $(TARGET).csp + diff --git a/Examples/Snake/Snake.som b/Examples/Snake/Snake.som new file mode 100644 index 0000000..f94ae8c --- /dev/null +++ b/Examples/Snake/Snake.som @@ -0,0 +1,100 @@ +" + +$Id: Snake.som 426 2008-05-22 08:22:07Z stefan.marr $ + +Copyright (c) 2001-2008 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Snake = ( + | head tail board | + + head: val = ( head := val ) + tail: val = ( tail := val ) + board: val = ( board := val ) + + moveLeft = ( + | newPos | + newPos := SnakeElement newWithX: head x Y: head y. + newPos x: (self overflow: (newPos x - 1) max: board width). + ^self move: newPos + ) + + moveRight = ( + | newPos | + newPos := SnakeElement newWithX: head x Y: head y. + newPos x: (self overflow: (newPos x + 1) max: board width). + ^self move: newPos + ) + + moveUp = ( + | newPos | + newPos := SnakeElement newWithX: head x Y: head y. + newPos y: (self overflow: (newPos y - 1) max: board height). + ^self move: newPos + ) + + moveDown = ( + | newPos | + newPos := SnakeElement newWithX: head x Y: head y. + newPos y: (self overflow: (newPos y + 1) max: board height). + ^self move: newPos + ) + + move: newPos = ( + newPos next: head. + head prev: newPos. + head := newPos. + + (board isAppleAtX: (newPos x) Y: (newPos y)) ifTrue: [ + board addApple + ] ifFalse: [ + + (board isSnakeAtX: newPos x Y: newPos y) ifTrue: [ + ^false + ]. + board remove: tail. + tail := tail prev. + tail next: nil. + ]. + board add: newPos. + + ^true + ) + + overflow: val max: max = ( + (val < 1) ifTrue: [ val := max + val ]. + (val > max) ifTrue: [ val := val - max ]. + ^val + ) + + ---- + newWithX: x Y: y andBoard: board = ( + | newSnake head | + newSnake := Snake new. + head := SnakeElement newWithX: x Y: y. + + newSnake head: head. + newSnake tail: head. + newSnake board: board. + board add: head. + ^newSnake + ) +) diff --git a/Examples/Snake/SnakeElement.som b/Examples/Snake/SnakeElement.som new file mode 100644 index 0000000..215ba07 --- /dev/null +++ b/Examples/Snake/SnakeElement.som @@ -0,0 +1,33 @@ +" + +$Id: SnakeElement.som 191 2008-04-10 18:15:47Z michael.haupt $ + +Copyright (c) 2001-2008 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +SnakeElement = Element ( + | next prev | + next = ( ^next ) + next: val = ( next := val ) + + prev = ( ^prev ) + prev: val = ( prev := val ) +) diff --git a/Examples/Snake/Terminal.cpp b/Examples/Snake/Terminal.cpp new file mode 100644 index 0000000..3400e7f --- /dev/null +++ b/Examples/Snake/Terminal.cpp @@ -0,0 +1,133 @@ +/* + * $Id: Terminal.c 426 2008-05-22 08:22:07Z stefan.marr $ + * +Copyright (c) 2001-2008 see AUTHORS file +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + +#include +#include +#include +#include + + +/*************************************************/ +#pragma mark * Included Headers * +/*************************************************/ + + +#include +#include +#include +#include + +#include + +#include +#include + +#include "Terminal.h" + +/*************************************************/ +#pragma mark * Primitive Foreward Declaration * +/*************************************************/ + + + +/*************************************************/ +/*************************************************/ +/*************************************************/ +#pragma mark * Primitive Implementatition here * +/*************************************************/ +/*************************************************/ +/*************************************************/ + + +struct termios old_tty; +Terminal::Terminal() : PrimitiveContainer() { + this->terminalStream = 0; + this->SetPrimitive("getChar", static_cast( + new (_HEAP) Routine(this, &Terminal::getChar))); + this->SetPrimitive("uninit", static_cast( + new (_HEAP) Routine(this, &Terminal::uninit))); + this->SetPrimitive("init", static_cast( + new (_HEAP) Routine(this, &Terminal::init))); + this->SetPrimitive("sleepFor_", static_cast( + new (_HEAP) Routine(this, &Terminal::sleepFor_))); +} + +void Terminal::getChar(VMObject* object, VMFrame* frame) { + char chr; + char result[2]; + pString str = NULL; + VMObject* vmStr = NULL; + frame->Pop(); + //VMObject self __attribute__((unused)) = SEND(frame, pop); + + if (read(terminalStream, &chr, sizeof(chr)) > 0) { + result[0] = chr; + result[1] = 0; + + str = pString(result); + vmStr = (VMObject*)_UNIVERSE->NewString(str); + frame->Push(vmStr); + } else { + frame->Push(Globals::NilObject()); + } +} + +void Terminal::uninit(VMObject* object, VMFrame* frame) { + close(terminalStream); + tcsetattr(0, TCSANOW, &old_tty); +} + +void Terminal::init(VMObject* object, VMFrame* frame) { + struct termios tty; + + // Perpare terminal settings and change to non-canonical mode for char-wise input + tcgetattr(0, &old_tty); + tty = old_tty; + tty.c_lflag = tty.c_lflag & ~(ECHO | ECHOK | ICANON); + tty.c_cc[VTIME] = 1; + tcsetattr(0, TCSANOW, &tty); + + terminalStream = open("/dev/tty", O_RDONLY | O_NONBLOCK); + if (terminalStream < 0) { + _UNIVERSE->ErrorExit("Could not open /dev/tty for read\n"); + } +} + +void Terminal::sleepFor_(VMObject* object, VMFrame* frame) { + VMInteger* miliSeconds = (VMInteger*)frame->Pop(); + int64_t sec = (int64_t)miliSeconds->GetEmbeddedInteger() * 1000; + sync(); + usleep(sec); +} + +/*************************************************/ +/*************************************************/ +/*************************************************/ +#pragma mark * EOF * +/*************************************************/ +/*************************************************/ +/*************************************************/ + diff --git a/Examples/Snake/Terminal.h b/Examples/Snake/Terminal.h new file mode 100644 index 0000000..c69847e --- /dev/null +++ b/Examples/Snake/Terminal.h @@ -0,0 +1,19 @@ +#pragma once + +#ifndef TERMINAL_H_ +#define TERMINAL_H_ + +#include + +class Terminal : public PrimitiveContainer { +public: + Terminal(); + void sleepFor_(VMObject* object, VMFrame* frame); + void getChar(VMObject* object, VMFrame* frame); + void uninit(VMObject* object, VMFrame* frame); + void init(VMObject* object, VMFrame* frame); +private: + int terminalStream; +}; + +#endif; diff --git a/Examples/Snake/Terminal.som b/Examples/Snake/Terminal.som new file mode 100644 index 0000000..99f584c --- /dev/null +++ b/Examples/Snake/Terminal.som @@ -0,0 +1,94 @@ +" + +$Id: Terminal.som 191 2008-04-10 18:15:47Z michael.haupt $ + +Copyright (c) 2001-2008 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Terminal = ( + + ---- + KEY_UP = (^#key_up) + KEY_DOWN = (^#key_down) + KEY_LEFT = (^#key_left) + KEY_RIGHT = (^#key_right) + + init = primitive + + uninit = primitive + + cursorToX: x Y: y = ( + '[' print. + y print. + ';' print. + x print. + 'H' print. + ) + + clear = ( + '' print. + ) + + put: str = ( + str print + ) + + getChar = primitive + + get = ( + | chr result | + result := ''. + chr := self getChar. + + [ chr = nil ] whileFalse: [ + result := result + chr. + chr := self getChar + ]. + + ^self recognizeKeys: result. + ) + + recognizeKeys: chrs = ( + (chrs = '') ifTrue: [ + ^self KEY_UP. + ]. + + (chrs = '') ifTrue: [ + ^self KEY_DOWN. + ]. + + (chrs = '') ifTrue: [ + ^self KEY_RIGHT. + ]. + + (chrs = '') ifTrue: [ + ^self KEY_LEFT. + ]. + + (chrs = '') ifTrue: [ + ^nil. + ]. + + ^chrs + ) + + sleepFor: sec = primitive +) diff --git a/Examples/StringTest/StringTest.som b/Examples/StringTest/StringTest.som new file mode 100644 index 0000000..7a602b8 --- /dev/null +++ b/Examples/StringTest/StringTest.som @@ -0,0 +1,60 @@ +" + +$Id: StringTest.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +StringTest = ( + + "The 'run' method is called when initializing the system" + run = ( + |str1 str2 str3| + + "test equality (true, false, true)" + str1 := 'foo'. + str2 := 'bar'. + + (str1 = str1) println. + (str1 = str2) println. + (str2 = str2) println. + + "test length (6)" + str3 := str1 + str2. + str3 length println. + + "test charAt" + (str3 charAt: 0) println. + (str3 charAt: 1) println. + (str3 charAt: 2) println. + (str3 charAt: 3) println. + (str3 charAt: 4) println. + (str3 charAt: 5) println. + + "test substring. 'foo' , 'bar' , 'foobar'" + (str3 primSubstringFrom: 0 To: 2) println. + (str3 primSubstringFrom: 3 To: 5) println. + (str3 primSubstringFrom: 0 To: 5) println. + + 'Hello, World from SmallTalk(tm)' println + ) + +) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4a407a4 --- /dev/null +++ b/Makefile @@ -0,0 +1,47 @@ +#!/usr/bin/env make -f + +# +# Makefile by Tobias Pape +# $Id: Makefile 206 2008-04-14 12:22:39Z michael.haupt $ +# +# Copyright (c) 2007 Michael Haupt, Tobias Pape +# Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +# http://www.hpi.uni-potsdam.de/swa/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +export ROOT_DIR :=$(PWD) +export BUILD_DIR:=$(ROOT_DIR)/build +export SRC_DIR :=$(ROOT_DIR)/src +export LIB_DIR :=$(ROOT_DIR)/lib + +export ST_DIR =$(ROOT_DIR)/Smalltalk +export EX_DIR =$(ROOT_DIR)/Examples +export TEST_DIR =$(ROOT_DIR)/TestSuite + +ifeq ($(OS),) +# only Windows has OS predefined. + UNAME := $(shell uname -s) +else + UNAME :=windows +endif + +############# +include $(BUILD_DIR)/$(UNAME).make diff --git a/SOM.xcodeproj/default.pbxuser b/SOM.xcodeproj/default.pbxuser new file mode 100644 index 0000000..9dc27af --- /dev/null +++ b/SOM.xcodeproj/default.pbxuser @@ -0,0 +1,118 @@ +// !$*UTF8*$! +{ + 3F5202740FA661D900E75857 /* Project object */ = { + activeBuildConfigurationName = Debug; + activeExecutable = 3F7679640FA668C000E00AE8 /* SOM++ */; + activeTarget = 3F5202860FA661FF00E75857 /* SOM++ */; + codeSenseManager = 3F7679580FA6689200E00AE8 /* Code sense */; + executables = ( + 3F7679640FA668C000E00AE8 /* SOM++ */, + ); + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 22, + 300, + 228.58349609375, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXExecutablesDataSource_ActiveFlagID, + PBXExecutablesDataSource_NameID, + PBXExecutablesDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 341, + 20, + 48.16259765625, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 262564215; + PBXWorkspaceStateSaveDate = 262564215; + }; + sourceControlManager = 3F7679570FA6689200E00AE8 /* Source Control */; + userBuildSettings = { + }; + }; + 3F5202860FA661FF00E75857 /* SOM++ */ = { + activeExec = 0; + }; + 3F7679570FA6689200E00AE8 /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + }; + }; + 3F7679580FA6689200E00AE8 /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + 3F7679640FA668C000E00AE8 /* SOM++ */ = { + isa = PBXExecutable; + activeArgIndices = ( + YES, + ); + argumentStrings = ( + "-cp Smalltalk", + ); + autoAttachOnCrash = 1; + breakpointsEnabled = 0; + configStateDict = { + "PBXLSLaunchAction-0" = { + PBXLSLaunchAction = 0; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXLSRunLaunchConfig; + commandLineArgs = ( + ); + displayName = "Executable Runner"; + environment = { + }; + identifier = com.apple.Xcode.launch.runConfig; + remoteHostInfo = ""; + startActionInfo = ""; + }; + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + launchableReference = 3F7679650FA668C000E00AE8 /* SOM++ */; + libgmallocEnabled = 0; + name = "SOM++"; + sourceDirectories = ( + ); + startupPath = "<>"; + }; + 3F7679650FA668C000E00AE8 /* SOM++ */ = { + isa = PBXFileReference; + lastKnownFileType = "compiled.mach-o.executable"; + path = "SOM++"; + sourceTree = ""; + }; +} diff --git a/SOM.xcodeproj/project.pbxproj b/SOM.xcodeproj/project.pbxproj new file mode 100644 index 0000000..745724c --- /dev/null +++ b/SOM.xcodeproj/project.pbxproj @@ -0,0 +1,400 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXFileReference section */ + 34FB20870FAC73020009EE70 /* VMPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMPointer.h; sourceTree = ""; }; + 34FB20880FAC73020009EE70 /* VMPointerConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMPointerConverter.h; sourceTree = ""; }; + 3F5202930FA6624C00E75857 /* build_darwin.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = build_darwin.sh; sourceTree = ""; }; + 3F5202940FA6624C00E75857 /* Darwin.make */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Darwin.make; sourceTree = ""; }; + 3F5202950FA6624C00E75857 /* Linux.make */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Linux.make; sourceTree = ""; }; + 3F5202A40FA6624C00E75857 /* windows.make */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = windows.make; sourceTree = ""; }; + 3F5202F10FA6624C00E75857 /* BytecodeGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BytecodeGenerator.cpp; sourceTree = ""; }; + 3F5202F20FA6624C00E75857 /* BytecodeGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeGenerator.h; sourceTree = ""; }; + 3F5202F30FA6624C00E75857 /* ClassGenerationContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClassGenerationContext.cpp; sourceTree = ""; }; + 3F5202F40FA6624C00E75857 /* ClassGenerationContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassGenerationContext.h; sourceTree = ""; }; + 3F5202F50FA6624C00E75857 /* Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Disassembler.cpp; sourceTree = ""; }; + 3F5202F60FA6624C00E75857 /* Disassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Disassembler.h; sourceTree = ""; }; + 3F5202F70FA6624C00E75857 /* Lexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lexer.cpp; sourceTree = ""; }; + 3F5202F80FA6624C00E75857 /* Lexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lexer.h; sourceTree = ""; }; + 3F5202F90FA6624C00E75857 /* MethodGenerationContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MethodGenerationContext.cpp; sourceTree = ""; }; + 3F5202FA0FA6624C00E75857 /* MethodGenerationContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodGenerationContext.h; sourceTree = ""; }; + 3F5202FB0FA6624C00E75857 /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Parser.cpp; sourceTree = ""; }; + 3F5202FC0FA6624C00E75857 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Parser.h; sourceTree = ""; }; + 3F5202FD0FA6624C00E75857 /* SourcecodeCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourcecodeCompiler.cpp; sourceTree = ""; }; + 3F5202FE0FA6624C00E75857 /* SourcecodeCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourcecodeCompiler.h; sourceTree = ""; }; + 3F5202FF0FA6624C00E75857 /* cppsom_dll.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = cppsom_dll.vcproj; sourceTree = ""; }; + 3F5203010FA6624C00E75857 /* bytecodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bytecodes.cpp; sourceTree = ""; }; + 3F5203020FA6624C00E75857 /* bytecodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bytecodes.h; sourceTree = ""; }; + 3F5203030FA6624C00E75857 /* Interpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Interpreter.cpp; sourceTree = ""; }; + 3F5203040FA6624C00E75857 /* Interpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Interpreter.h; sourceTree = ""; }; + 3F5203050FA6624C00E75857 /* Main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Main.cpp; sourceTree = ""; }; + 3F5203070FA6624C00E75857 /* GarbageCollector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GarbageCollector.cpp; sourceTree = ""; }; + 3F5203080FA6624C00E75857 /* GarbageCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GarbageCollector.h; sourceTree = ""; }; + 3F5203090FA6624C00E75857 /* Heap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Heap.cpp; sourceTree = ""; }; + 3F52030A0FA6624C00E75857 /* Heap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Heap.h; sourceTree = ""; }; + 3F52030C0FA6624C00E75857 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = ""; }; + 3F52030D0FA6624C00E75857 /* defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = defs.h; sourceTree = ""; }; + 3F52030E0FA6624C00E75857 /* ExtendedList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtendedList.h; sourceTree = ""; }; + 3F52030F0FA6624C00E75857 /* gettimeofday.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gettimeofday.h; sourceTree = ""; }; + 3F5203100FA6624C00E75857 /* HashMap.h.bak */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HashMap.h.bak; sourceTree = ""; }; + 3F5203120FA6624C00E75857 /* Array.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Array.cpp; sourceTree = ""; }; + 3F5203130FA6624C00E75857 /* Array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Array.h; sourceTree = ""; }; + 3F5203140FA6624C00E75857 /* BigInteger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BigInteger.cpp; sourceTree = ""; }; + 3F5203150FA6624C00E75857 /* BigInteger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BigInteger.h; sourceTree = ""; }; + 3F5203160FA6624C00E75857 /* Block.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Block.cpp; sourceTree = ""; }; + 3F5203170FA6624C00E75857 /* Block.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Block.h; sourceTree = ""; }; + 3F5203180FA6624C00E75857 /* Class.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Class.cpp; sourceTree = ""; }; + 3F5203190FA6624C00E75857 /* Class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Class.h; sourceTree = ""; }; + 3F52031A0FA6624C00E75857 /* Core.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Core.cpp; sourceTree = ""; }; + 3F52031B0FA6624C00E75857 /* Core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Core.h; sourceTree = ""; }; + 3F52031C0FA6624C00E75857 /* Double.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Double.cpp; sourceTree = ""; }; + 3F52031D0FA6624C00E75857 /* Double.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Double.h; sourceTree = ""; }; + 3F52031E0FA6624C00E75857 /* Integer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Integer.cpp; sourceTree = ""; }; + 3F52031F0FA6624C00E75857 /* Integer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Integer.h; sourceTree = ""; }; + 3F5203200FA6624C00E75857 /* Object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Object.cpp; sourceTree = ""; }; + 3F5203210FA6624C00E75857 /* Object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Object.h; sourceTree = ""; }; + 3F5203220FA6624C00E75857 /* String.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = String.cpp; sourceTree = ""; }; + 3F5203230FA6624C00E75857 /* String.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = String.h; sourceTree = ""; }; + 3F5203240FA6624C00E75857 /* Symbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Symbol.cpp; sourceTree = ""; }; + 3F5203250FA6624C00E75857 /* Symbol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Symbol.h; sourceTree = ""; }; + 3F5203260FA6624C00E75857 /* System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = System.cpp; sourceTree = ""; }; + 3F5203270FA6624C00E75857 /* System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = System.h; sourceTree = ""; }; + 3F5203290FA6624C00E75857 /* PrimitiveContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrimitiveContainer.cpp; sourceTree = ""; }; + 3F52032A0FA6624C00E75857 /* PrimitiveContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrimitiveContainer.h; sourceTree = ""; }; + 3F52032B0FA6624C00E75857 /* PrimitiveLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrimitiveLoader.cpp; sourceTree = ""; }; + 3F52032C0FA6624C00E75857 /* PrimitiveLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrimitiveLoader.h; sourceTree = ""; }; + 3F52032D0FA6624C00E75857 /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = ""; }; + 3F52032E0FA6624C00E75857 /* Routine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Routine.h; sourceTree = ""; }; + 3F5203300FA6624C00E75857 /* Shell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shell.cpp; sourceTree = ""; }; + 3F5203310FA6624C00E75857 /* Shell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shell.h; sourceTree = ""; }; + 3F5203320FA6624C00E75857 /* Universe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Universe.cpp; sourceTree = ""; }; + 3F5203330FA6624C00E75857 /* Universe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Universe.h; sourceTree = ""; }; + 3F5203350FA6624C00E75857 /* ObjectFormats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectFormats.h; sourceTree = ""; }; + 3F5203360FA6624C00E75857 /* PrimitiveRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrimitiveRoutine.h; sourceTree = ""; }; + 3F5203370FA6624C00E75857 /* Signature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Signature.cpp; sourceTree = ""; }; + 3F5203380FA6624C00E75857 /* Signature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Signature.h; sourceTree = ""; }; + 3F5203390FA6624C00E75857 /* Symboltable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Symboltable.cpp; sourceTree = ""; }; + 3F52033A0FA6624C00E75857 /* Symboltable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Symboltable.h; sourceTree = ""; }; + 3F52033B0FA6624C00E75857 /* VMArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMArray.cpp; sourceTree = ""; }; + 3F52033C0FA6624C00E75857 /* VMArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMArray.h; sourceTree = ""; }; + 3F52033D0FA6624C00E75857 /* VMBigInteger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMBigInteger.cpp; sourceTree = ""; }; + 3F52033E0FA6624C00E75857 /* VMBigInteger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMBigInteger.h; sourceTree = ""; }; + 3F52033F0FA6624C00E75857 /* VMBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMBlock.cpp; sourceTree = ""; }; + 3F5203400FA6624C00E75857 /* VMBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMBlock.h; sourceTree = ""; }; + 3F5203410FA6624C00E75857 /* VMClass.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMClass.cpp; sourceTree = ""; }; + 3F5203420FA6624C00E75857 /* VMClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMClass.h; sourceTree = ""; }; + 3F5203430FA6624C00E75857 /* VMDouble.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMDouble.cpp; sourceTree = ""; }; + 3F5203440FA6624C00E75857 /* VMDouble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMDouble.h; sourceTree = ""; }; + 3F5203450FA6624C00E75857 /* VMEvaluationPrimitive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMEvaluationPrimitive.cpp; sourceTree = ""; }; + 3F5203460FA6624C00E75857 /* VMEvaluationPrimitive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMEvaluationPrimitive.h; sourceTree = ""; }; + 3F5203470FA6624C00E75857 /* VMFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMFrame.cpp; sourceTree = ""; }; + 3F5203480FA6624C00E75857 /* VMFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMFrame.h; sourceTree = ""; }; + 3F5203490FA6624C00E75857 /* VMFreeObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMFreeObject.cpp; sourceTree = ""; }; + 3F52034A0FA6624C00E75857 /* VMFreeObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMFreeObject.h; sourceTree = ""; }; + 3F52034B0FA6624C00E75857 /* VMInteger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMInteger.cpp; sourceTree = ""; }; + 3F52034C0FA6624C00E75857 /* VMInteger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInteger.h; sourceTree = ""; }; + 3F52034D0FA6624C00E75857 /* VMInvokable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMInvokable.cpp; sourceTree = ""; }; + 3F52034E0FA6624C00E75857 /* VMInvokable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInvokable.h; sourceTree = ""; }; + 3F52034F0FA6624C00E75857 /* VMMethod.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMMethod.cpp; sourceTree = ""; }; + 3F5203500FA6624C00E75857 /* VMMethod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMMethod.h; sourceTree = ""; }; + 3F5203510FA6624C00E75857 /* VMObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMObject.cpp; sourceTree = ""; }; + 3F5203520FA6624C00E75857 /* VMObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMObject.h; sourceTree = ""; }; + 3F5203530FA6624C00E75857 /* VMPrimitive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMPrimitive.cpp; sourceTree = ""; }; + 3F5203540FA6624C00E75857 /* VMPrimitive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMPrimitive.h; sourceTree = ""; }; + 3F5203550FA6624C00E75857 /* VMString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMString.cpp; sourceTree = ""; }; + 3F5203560FA6624C00E75857 /* VMString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMString.h; sourceTree = ""; }; + 3F5203570FA6624C00E75857 /* VMSymbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMSymbol.cpp; sourceTree = ""; }; + 3F5203580FA6624C00E75857 /* VMSymbol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMSymbol.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + 3F5202720FA661D900E75857 = { + isa = PBXGroup; + children = ( + 3F5202920FA6624C00E75857 /* build */, + 3F5202EF0FA6624C00E75857 /* src */, + ); + sourceTree = ""; + }; + 3F5202920FA6624C00E75857 /* build */ = { + isa = PBXGroup; + children = ( + 3F5202930FA6624C00E75857 /* build_darwin.sh */, + 3F5202940FA6624C00E75857 /* Darwin.make */, + 3F5202950FA6624C00E75857 /* Linux.make */, + 3F5202A40FA6624C00E75857 /* windows.make */, + ); + path = build; + sourceTree = ""; + }; + 3F5202EF0FA6624C00E75857 /* src */ = { + isa = PBXGroup; + children = ( + 3F5202F00FA6624C00E75857 /* compiler */, + 3F5202FF0FA6624C00E75857 /* cppsom_dll.vcproj */, + 3F5203000FA6624C00E75857 /* interpreter */, + 3F5203050FA6624C00E75857 /* Main.cpp */, + 3F5203060FA6624C00E75857 /* memory */, + 3F52030B0FA6624C00E75857 /* misc */, + 3F5203110FA6624C00E75857 /* primitives */, + 3F5203280FA6624C00E75857 /* primitivesCore */, + 3F52032F0FA6624C00E75857 /* vm */, + 3F5203340FA6624C00E75857 /* vmobjects */, + ); + path = src; + sourceTree = ""; + }; + 3F5202F00FA6624C00E75857 /* compiler */ = { + isa = PBXGroup; + children = ( + 3F5202F10FA6624C00E75857 /* BytecodeGenerator.cpp */, + 3F5202F20FA6624C00E75857 /* BytecodeGenerator.h */, + 3F5202F30FA6624C00E75857 /* ClassGenerationContext.cpp */, + 3F5202F40FA6624C00E75857 /* ClassGenerationContext.h */, + 3F5202F50FA6624C00E75857 /* Disassembler.cpp */, + 3F5202F60FA6624C00E75857 /* Disassembler.h */, + 3F5202F70FA6624C00E75857 /* Lexer.cpp */, + 3F5202F80FA6624C00E75857 /* Lexer.h */, + 3F5202F90FA6624C00E75857 /* MethodGenerationContext.cpp */, + 3F5202FA0FA6624C00E75857 /* MethodGenerationContext.h */, + 3F5202FB0FA6624C00E75857 /* Parser.cpp */, + 3F5202FC0FA6624C00E75857 /* Parser.h */, + 3F5202FD0FA6624C00E75857 /* SourcecodeCompiler.cpp */, + 3F5202FE0FA6624C00E75857 /* SourcecodeCompiler.h */, + ); + path = compiler; + sourceTree = ""; + }; + 3F5203000FA6624C00E75857 /* interpreter */ = { + isa = PBXGroup; + children = ( + 3F5203010FA6624C00E75857 /* bytecodes.cpp */, + 3F5203020FA6624C00E75857 /* bytecodes.h */, + 3F5203030FA6624C00E75857 /* Interpreter.cpp */, + 3F5203040FA6624C00E75857 /* Interpreter.h */, + ); + path = interpreter; + sourceTree = ""; + }; + 3F5203060FA6624C00E75857 /* memory */ = { + isa = PBXGroup; + children = ( + 3F5203070FA6624C00E75857 /* GarbageCollector.cpp */, + 3F5203080FA6624C00E75857 /* GarbageCollector.h */, + 3F5203090FA6624C00E75857 /* Heap.cpp */, + 3F52030A0FA6624C00E75857 /* Heap.h */, + ); + path = memory; + sourceTree = ""; + }; + 3F52030B0FA6624C00E75857 /* misc */ = { + isa = PBXGroup; + children = ( + 3F52030C0FA6624C00E75857 /* debug.h */, + 3F52030D0FA6624C00E75857 /* defs.h */, + 3F52030E0FA6624C00E75857 /* ExtendedList.h */, + 3F52030F0FA6624C00E75857 /* gettimeofday.h */, + 3F5203100FA6624C00E75857 /* HashMap.h.bak */, + ); + path = misc; + sourceTree = ""; + }; + 3F5203110FA6624C00E75857 /* primitives */ = { + isa = PBXGroup; + children = ( + 3F5203120FA6624C00E75857 /* Array.cpp */, + 3F5203130FA6624C00E75857 /* Array.h */, + 3F5203140FA6624C00E75857 /* BigInteger.cpp */, + 3F5203150FA6624C00E75857 /* BigInteger.h */, + 3F5203160FA6624C00E75857 /* Block.cpp */, + 3F5203170FA6624C00E75857 /* Block.h */, + 3F5203180FA6624C00E75857 /* Class.cpp */, + 3F5203190FA6624C00E75857 /* Class.h */, + 3F52031A0FA6624C00E75857 /* Core.cpp */, + 3F52031B0FA6624C00E75857 /* Core.h */, + 3F52031C0FA6624C00E75857 /* Double.cpp */, + 3F52031D0FA6624C00E75857 /* Double.h */, + 3F52031E0FA6624C00E75857 /* Integer.cpp */, + 3F52031F0FA6624C00E75857 /* Integer.h */, + 3F5203200FA6624C00E75857 /* Object.cpp */, + 3F5203210FA6624C00E75857 /* Object.h */, + 3F5203220FA6624C00E75857 /* String.cpp */, + 3F5203230FA6624C00E75857 /* String.h */, + 3F5203240FA6624C00E75857 /* Symbol.cpp */, + 3F5203250FA6624C00E75857 /* Symbol.h */, + 3F5203260FA6624C00E75857 /* System.cpp */, + 3F5203270FA6624C00E75857 /* System.h */, + ); + path = primitives; + sourceTree = ""; + }; + 3F5203280FA6624C00E75857 /* primitivesCore */ = { + isa = PBXGroup; + children = ( + 3F5203290FA6624C00E75857 /* PrimitiveContainer.cpp */, + 3F52032A0FA6624C00E75857 /* PrimitiveContainer.h */, + 3F52032B0FA6624C00E75857 /* PrimitiveLoader.cpp */, + 3F52032C0FA6624C00E75857 /* PrimitiveLoader.h */, + 3F52032D0FA6624C00E75857 /* resource.h */, + 3F52032E0FA6624C00E75857 /* Routine.h */, + ); + path = primitivesCore; + sourceTree = ""; + }; + 3F52032F0FA6624C00E75857 /* vm */ = { + isa = PBXGroup; + children = ( + 3F5203300FA6624C00E75857 /* Shell.cpp */, + 3F5203310FA6624C00E75857 /* Shell.h */, + 3F5203320FA6624C00E75857 /* Universe.cpp */, + 3F5203330FA6624C00E75857 /* Universe.h */, + ); + path = vm; + sourceTree = ""; + }; + 3F5203340FA6624C00E75857 /* vmobjects */ = { + isa = PBXGroup; + children = ( + 34FB20870FAC73020009EE70 /* VMPointer.h */, + 34FB20880FAC73020009EE70 /* VMPointerConverter.h */, + 3F5203350FA6624C00E75857 /* ObjectFormats.h */, + 3F5203360FA6624C00E75857 /* PrimitiveRoutine.h */, + 3F5203370FA6624C00E75857 /* Signature.cpp */, + 3F5203380FA6624C00E75857 /* Signature.h */, + 3F5203390FA6624C00E75857 /* Symboltable.cpp */, + 3F52033A0FA6624C00E75857 /* Symboltable.h */, + 3F52033B0FA6624C00E75857 /* VMArray.cpp */, + 3F52033C0FA6624C00E75857 /* VMArray.h */, + 3F52033D0FA6624C00E75857 /* VMBigInteger.cpp */, + 3F52033E0FA6624C00E75857 /* VMBigInteger.h */, + 3F52033F0FA6624C00E75857 /* VMBlock.cpp */, + 3F5203400FA6624C00E75857 /* VMBlock.h */, + 3F5203410FA6624C00E75857 /* VMClass.cpp */, + 3F5203420FA6624C00E75857 /* VMClass.h */, + 3F5203430FA6624C00E75857 /* VMDouble.cpp */, + 3F5203440FA6624C00E75857 /* VMDouble.h */, + 3F5203450FA6624C00E75857 /* VMEvaluationPrimitive.cpp */, + 3F5203460FA6624C00E75857 /* VMEvaluationPrimitive.h */, + 3F5203470FA6624C00E75857 /* VMFrame.cpp */, + 3F5203480FA6624C00E75857 /* VMFrame.h */, + 3F5203490FA6624C00E75857 /* VMFreeObject.cpp */, + 3F52034A0FA6624C00E75857 /* VMFreeObject.h */, + 3F52034B0FA6624C00E75857 /* VMInteger.cpp */, + 3F52034C0FA6624C00E75857 /* VMInteger.h */, + 3F52034D0FA6624C00E75857 /* VMInvokable.cpp */, + 3F52034E0FA6624C00E75857 /* VMInvokable.h */, + 3F52034F0FA6624C00E75857 /* VMMethod.cpp */, + 3F5203500FA6624C00E75857 /* VMMethod.h */, + 3F5203510FA6624C00E75857 /* VMObject.cpp */, + 3F5203520FA6624C00E75857 /* VMObject.h */, + 3F5203530FA6624C00E75857 /* VMPrimitive.cpp */, + 3F5203540FA6624C00E75857 /* VMPrimitive.h */, + 3F5203550FA6624C00E75857 /* VMString.cpp */, + 3F5203560FA6624C00E75857 /* VMString.h */, + 3F5203570FA6624C00E75857 /* VMSymbol.cpp */, + 3F5203580FA6624C00E75857 /* VMSymbol.h */, + ); + path = vmobjects; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + 3F5202860FA661FF00E75857 /* SOM++ */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "build/build_darwin.sh $MAKE_ARGS"; + buildConfigurationList = 3F52028D0FA6621600E75857 /* Build configuration list for PBXLegacyTarget "SOM++" */; + buildPhases = ( + ); + buildToolPath = /bin/sh; + dependencies = ( + ); + name = "SOM++"; + passBuildSettingsInEnvironment = 0; + productName = "SOM++"; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXProject section */ + 3F5202740FA661D900E75857 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 3F5202770FA661D900E75857 /* Build configuration list for PBXProject "SOM" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 0; + mainGroup = 3F5202720FA661D900E75857; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 3F5202860FA661FF00E75857 /* SOM++ */, + ); + }; +/* End PBXProject section */ + +/* Begin XCBuildConfiguration section */ + 3F5202750FA661D900E75857 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + MAKE_ARGS = debug; + }; + name = Debug; + }; + 3F5202760FA661D900E75857 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + MAKE_ARGS = all; + }; + name = Release; + }; + 3F5202870FA661FF00E75857 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + PRODUCT_NAME = "SOM++"; + }; + name = Debug; + }; + 3F5202880FA661FF00E75857 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PRODUCT_NAME = "SOM++"; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3F5202770FA661D900E75857 /* Build configuration list for PBXProject "SOM" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3F5202750FA661D900E75857 /* Debug */, + 3F5202760FA661D900E75857 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3F52028D0FA6621600E75857 /* Build configuration list for PBXLegacyTarget "SOM++" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3F5202870FA661FF00E75857 /* Debug */, + 3F5202880FA661FF00E75857 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3F5202740FA661D900E75857 /* Project object */; +} diff --git a/Smalltalk/Array.som b/Smalltalk/Array.som new file mode 100644 index 0000000..735d86b --- /dev/null +++ b/Smalltalk/Array.som @@ -0,0 +1,67 @@ +" + +$Id: Array.som 663 2008-06-17 10:33:01Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Array = ( + + "Accessing" + at: index = primitive + at: index put: value = primitive + length = primitive + putAll: block = ( self doIndexes: [ :i | + self at: i put: block value ] ) + + "Iterating" + do: block = ( self doIndexes: [ :i | + block value: (self at: i) ] ) + doIndexes: block = ( | i | i := 1. [ i <= (self length) ] whileTrue: + [ block value: i. i := i + 1 ] ) + + from: start to: end do: block = ( | i | + i := start. + [ i <= self length ] whileTrue: [ + block value: (self at: i). + i := i + 1 ] + ) + + "Containment check" + contains: element = ( self do: [ :e | e = element ifTrue: [ ^true ] ]. + ^false ) + + "Collection" + collect: aBlock = ( + | result | + result := Array new: self length. + self doIndexes: [ :i | result at: i put: (aBlock value: (self at: i)) ]. + ^result + ) + + ---------------------------- + + "Allocation" + new = ( ^self new: 0 ) + new: length = primitive + new: length withAll: block = ( ^((self new: length) putAll: block) ) + +) diff --git a/Smalltalk/BigInteger.som b/Smalltalk/BigInteger.som new file mode 100644 index 0000000..cdd22b9 --- /dev/null +++ b/Smalltalk/BigInteger.som @@ -0,0 +1,64 @@ +" + +$Id: BigInteger.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +BigInteger = ( + + "Arithmetic" + + argument = primitive + - argument = primitive + * argument = primitive + / argument = primitive + % argument = primitive + & argument = primitive + abs = ( ^(self < 0) ifTrue: (0 - self) ifFalse: self ) + sqrt = primitive + negated = ( ^0 - self ) + + "Comparing" + = argument = primitive + < argument = primitive + > argument = ( ^(self >= argument) and: [ self <> argument ] ) + >= argument = ( ^(self < argument) not ) + <= argument = ( ^(self < argument) or: [ self = argument ] ) + negative = ( ^self < 0 ) + between: a and: b = ( ^(self > a) and: [ self < b ] ) + + "Converting" + asString = primitive + + "Iterating" + to: limit do: block = ( + | i | + i := self. + [ i <= limit ] whileTrue: [ block value: i. i := i + 1 ] + ) + + downTo: limit do: block = ( + | i | + i := self. + [ i >= limit ] whileTrue: [ block value: i. i := i - 1 ] + ) + +) diff --git a/Smalltalk/Block.som b/Smalltalk/Block.som new file mode 100644 index 0000000..b7a1044 --- /dev/null +++ b/Smalltalk/Block.som @@ -0,0 +1,49 @@ +" + +$Id: Block.som 220 2008-04-20 07:37:15Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Block = ( + + "For the creation of Block instances, see Universe_new_block()." + + | method context | + + "Evaluation" + value = primitive + + "Looping" + whileFalse: block = ( + [ self value not ] whileTrue: block + ) + + whileTrue: block = ( + (self value) ifFalse: [ ^nil ]. + block value. + self restart + ) + + "Restarting" + restart = primitive + +) diff --git a/Smalltalk/Block1.som b/Smalltalk/Block1.som new file mode 100644 index 0000000..cbbef0e --- /dev/null +++ b/Smalltalk/Block1.som @@ -0,0 +1,33 @@ +" + +$Id: Block1.som 220 2008-04-20 07:37:15Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Block1 = Block ( + + "For the creation of Block instances, see Universe_new_block()." + + "Evaluating" + value = primitive + +) diff --git a/Smalltalk/Block2.som b/Smalltalk/Block2.som new file mode 100644 index 0000000..23f2917 --- /dev/null +++ b/Smalltalk/Block2.som @@ -0,0 +1,34 @@ +" + +$Id: Block2.som 220 2008-04-20 07:37:15Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Block2 = Block ( + + "For the creation of Block instances, see Universe_new_block()." + + "Evaluating" + value = ( self value: nil ) + value: argument = primitive + +) diff --git a/Smalltalk/Block3.som b/Smalltalk/Block3.som new file mode 100644 index 0000000..19e9302 --- /dev/null +++ b/Smalltalk/Block3.som @@ -0,0 +1,35 @@ +" + +$Id: Block3.som 220 2008-04-20 07:37:15Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Block3 = Block ( + + "For the creation of Block instances, see Universe_new_block()." + + "Evaluating" + value = ( self value: nil with: nil ) + value: arg = ( self value: arg with: nil ) + value: arg1 with: arg2 = primitive + +) \ No newline at end of file diff --git a/Smalltalk/Boolean.som b/Smalltalk/Boolean.som new file mode 100644 index 0000000..b7d17d4 --- /dev/null +++ b/Smalltalk/Boolean.som @@ -0,0 +1,39 @@ +" + +$Id: Boolean.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Boolean = ( + + "Conditional evaluation" + ifTrue: trueBlock ifFalse: falseBlock = ( + self ifTrue: [ ^trueBlock value ]. + self ifFalse: [ ^falseBlock value ]. + ) + + "Logical operations" + || boolean = ( ^self or: boolean ) + && boolean = ( ^self and: boolean ) + +) + diff --git a/Smalltalk/Class.som b/Smalltalk/Class.som new file mode 100644 index 0000000..37d5a9a --- /dev/null +++ b/Smalltalk/Class.som @@ -0,0 +1,50 @@ +" + +$Id: Class.som 225 2008-04-21 12:23:00Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Class = ( + + | superClass name instanceFields instanceInvokables | + + "Accessing" + name = ( ^name ) + + "Converting" + asString = ( ^self name asString ) + + "Allocation" + new = primitive + + "Meta Information" + superclass = ( ^superClass ) + fields = ( ^instanceFields ) + methods = ( ^instanceInvokables ) + + hasMethod: aSymbol = ( + instanceInvokables do: [ :m | + m signature = aSymbol ifTrue: [ ^true ] ]. + ^false + ) + +) diff --git a/Smalltalk/Dictionary.som b/Smalltalk/Dictionary.som new file mode 100644 index 0000000..dfca33f --- /dev/null +++ b/Smalltalk/Dictionary.som @@ -0,0 +1,69 @@ +" + +$Id: Dictionary.som 111 2007-09-18 09:21:40Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Dictionary = ( + + | pairs | + + at: aKey put: aValue = ( + (self containsKey: aKey) + ifTrue: [ (self pairAt: aKey) value: aValue ] + ifFalse: [ pairs add: (Pair withKey: aKey andValue: aValue) ] + ) + + at: aKey = ( + pairs do: [ :p | p key = aKey ifTrue: [ ^p value ] ]. + ^nil + ) + + containsKey: aKey = ( + pairs do: [ :p | p key = aKey ifTrue: [ ^true ] ]. + ^false + ) + + "Iteration" + do: block = ( pairs do: block ) + + "Private" + pairs: aSet = ( pairs := aSet ) + pairAt: aKey = ( + pairs do: [ :p | p key = aKey ifTrue: [ ^p ] ]. + ^nil + ) + + "Printing" + print = ( '{' print. pairs do: [ :p | p print ]. '}' print ) + println = ( self print. '' println ) + + ---- + + new = ( + | newDictionary | + newDictionary := super new. + newDictionary pairs: Set new. + ^newDictionary + ) + +) diff --git a/Smalltalk/Double.som b/Smalltalk/Double.som new file mode 100644 index 0000000..8b7eab2 --- /dev/null +++ b/Smalltalk/Double.som @@ -0,0 +1,64 @@ +" + +$Id: Double.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Double = ( + + "Arithmetic" + + argument = primitive + - argument = primitive + * argument = primitive + // argument = primitive + % argument = primitive + & argument = primitive + abs = ( ^(self < 0) ifTrue: (0 - self) ifFalse: self ) + sqrt = primitive + negated = ( ^0 - self ) + + "Comparing" + = argument = primitive + < argument = primitive + > argument = ( ^(self >= argument) and: [ self <> argument ] ) + >= argument = ( ^(self < argument) not ) + <= argument = ( ^(self < argument) or: [ self = argument ] ) + negative = ( ^self < 0 ) + between: a and: b = ( ^(self > a) and: [ self < b ] ) + + "Converting" + asString = primitive + + "Iterating" + to: limit do: block = ( + | i | + i := self. + [ i <= limit ] whileTrue: [ block value: i. i := i + 1 ] + ) + + downTo: limit do: block = ( + | i | + i := self. + [ i >= limit ] whileTrue: [ block value: i. i := i - 1 ] + ) + +) diff --git a/Smalltalk/False.som b/Smalltalk/False.som new file mode 100644 index 0000000..4219b33 --- /dev/null +++ b/Smalltalk/False.som @@ -0,0 +1,40 @@ +" + +$Id: False.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +False = Boolean ( + + "Converting" + asString = ( ^'false' ) + + "Conditional evaluation" + ifTrue: block = ( ^nil ) + ifFalse: block = ( ^block value ) + + "Logical operations" + not = ( ^true ) + or: block = ( ^block value ) + and: block = ( ^false ) + +) diff --git a/Smalltalk/Frame.som b/Smalltalk/Frame.som new file mode 100644 index 0000000..b91ef7c --- /dev/null +++ b/Smalltalk/Frame.som @@ -0,0 +1,34 @@ +" + +$Id: Frame.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Frame = Array ( + + | previousFrame context method | + + "getters for Frame properties" + previousFrame = ( ^previousFrame ) + method = ( ^method ) + +) diff --git a/Smalltalk/HashEntry.som b/Smalltalk/HashEntry.som new file mode 100644 index 0000000..b694417 --- /dev/null +++ b/Smalltalk/HashEntry.som @@ -0,0 +1,122 @@ +" + +$Id: HashEntry.som 111 2007-09-18 09:21:40Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +" +This class is not meant for direct use - it's an internal datastructure +for Hashtable +" + +HashEntry = ( + + | key value next hash | + + key = ( ^key ) + value = ( ^value ) + next = ( ^next ) + hash = ( ^hash ) + + key: k = ( key := k ) + value: v = ( value := v ) + next: n = ( next := n ) + hash: h = ( hash := h ) + + setKey: key value: value = ( + key = self key + ifTrue: [ self value: value. ^false. ] + ifFalse: [ + next isNil + ifTrue: [ + self next: (HashEntry newKey: key value: value next: nil). + ^true. ] + ifFalse: [ + ^(self next setKey: key value: value) ] ]. + ) + + getValue: key = ( + key = self key ifTrue: [ ^value ]. + next isNil ifTrue: [ ^nil ]. + ^next getValue: key. + ) + + containsKey: key = ( + key = self key ifTrue: [ ^true ]. + next isNil ifTrue: [ ^false ]. + ^next containsKey: key. + ) + + containsValue: value = ( + value = self value ifTrue: [ ^true ]. + next isNil ifTrue: [ ^false ]. + ^next containsValue: value. + ) + + keys = ( + next isNil + ifTrue: [ ^Vector new append: key ] + ifFalse: [ ^(next keys), key ] + ) + + values = ( + next isNil + ifTrue: [ ^Vector new append: value ] + ifFalse: [ ^(next values), value ] + ) + + run = ( | he | + he := HashEntry + newKey: 1 + value: 'a' + next: (HashEntry newKey: 2 value: 'b' next: nil). + + "he keys print. + ': ' print. + he values print. + ' (expected: Vector(2, 1, ): Vector(b, a, )' println. + " + + (he containsValue: 'a') ifFalse: [ 'containsValue: a failed' println ]. + (he containsValue: 'b') ifFalse: [ 'containsValue: b failed' println ]. + (he containsKey: 1) ifFalse: [ 'containsKey: 1 failed' println ]. + (he containsKey: 2) ifFalse: [ 'containsKey: 2 failed' println ]. + (he getValue: 1) = 'a' ifFalse: [ 'getValue: 1 not a' println ]. + (he getValue: 2) = 'b' ifFalse: [ 'getValue: 2 not b' println ]. + he setKey: true value: false. + (he getValue: true) = false ifFalse: [ + 'getValue: true is not false' println ]. + ) + + ---- + + newKey: k value: v next: n = ( + | newEntry | + newEntry := super new. + newEntry key: k. + newEntry value: v. + newEntry next: n. + newEntry hash: (k hashcode). + ^newEntry + ) + +) diff --git a/Smalltalk/Hashtable.som b/Smalltalk/Hashtable.som new file mode 100644 index 0000000..327cd1c --- /dev/null +++ b/Smalltalk/Hashtable.som @@ -0,0 +1,102 @@ +" + +$Id: Hashtable.som 263 2008-05-07 07:32:32Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Hashtable = ( + + | table count | + + "Testing" + containsKey: key = ( | idx e | + idx := self indexForKey: key. + e := table at: idx. + e isNil ifFalse: [ e keys do: [ :k | k = key ifTrue: [ ^true ] ] ]. + ^false. + ) + + containsValue: val = ( + table do: [ :ent | + ent isNil ifFalse: [ + ent values do: [ :v | v = val ifTrue: [ ^true ] ] ] ]. + ^false. + ) + + isEmpty = ( ^count = 0 ) + size = ( ^count ) + + "Accessing" + get: key = ( | idx e | + idx := self indexForKey: key. + e := table at: idx. + e isNil ifTrue: [ ^nil ]. + ^e getValue: key. + ) + + at: key put: value = ( | idx | + idx := self indexForKey: key. + (table at: idx) isNil + ifTrue: [ + table at: idx put: + (HashEntry newKey: key value: value next: nil). + count := count + 1 ] + ifFalse: [ + ((table at: idx) setKey: key value: value) + ifTrue: [ count := count + 1 ] ]. + "TODO: enlarge table, rehash if too large" + ) + + "TODO: some way to delete keys'd be nice..." + + "Enumerate" + keys = ( | vec | + vec = Vector new. + table do: [ :ent | + ent isNil ifFalse: [ ent keys do: [ :k | vec append: k ] ] ]. + ^vec. + ) + + values = ( | vec | + vec = Vector new. + table do: [ :ent | + ent isNil ifFalse: [ ent values do: [ :v | vec append: v ] ] ]. + ^vec. + ) + + "Clearing" + clear = ( table := Array new: 11. + count := 0 ) + + "Private" + indexForKey: aKey = ( ^(aKey hashcode % table length) abs + 1 ) + + ---------------- + + "Allocation" + new = ( | ht | + ht := super new. + ht clear. + ^ht. + ) + +) diff --git a/Smalltalk/Integer.som b/Smalltalk/Integer.som new file mode 100644 index 0000000..36abc51 --- /dev/null +++ b/Smalltalk/Integer.som @@ -0,0 +1,90 @@ +" + +$Id: Integer.som 663 2008-06-17 10:33:01Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Integer = ( + + "Arithmetic" + + argument = primitive + - argument = primitive + * argument = primitive + / argument = primitive + // argument = primitive + % argument = primitive + & argument = primitive + abs = ( ^(self < 0) ifTrue: (0 - self) ifFalse: self ) + sqrt = primitive + negated = ( ^0 - self ) + + "Random numbers" + atRandom = primitive + + "Comparing" + = argument = primitive + < argument = primitive + > argument = ( ^(self >= argument) and: [ self <> argument ] ) + >= argument = ( ^(self < argument) not ) + <= argument = ( ^(self < argument) or: [ self = argument ] ) + negative = ( ^self < 0 ) + between: a and: b = ( ^(self > a) and: [ self < b ] ) + + "Converting" + asString = primitive + hashcode = ( ^self ) + + "Iterating" + to: limit do: block = ( + self to: limit by: 1 do: block + ) + + to: limit by: step do: block = ( + | i | + i := self. + [ i <= limit ] whileTrue: [ block value: i. i := i + step ] + ) + + downTo: limit do: block = ( + self downTo: limit by: 1 do: block + ) + + downTo: limit by: step do: block = ( + | i | + i := self. + [ i >= limit ] whileTrue: [ block value: i. i := i - step ] + ) + + "More Iterations" + timesRepeat: block = ( + 1 to: self do: [ :i | block value ] + ) + + "Range Creation" + to: upper = ( + | range | + range := Array new: upper - self + 1. + self to: upper do: [ :i | range at: i put: i ]. + ^range + ) + +) diff --git a/Smalltalk/Metaclass.som b/Smalltalk/Metaclass.som new file mode 100644 index 0000000..a2224ba --- /dev/null +++ b/Smalltalk/Metaclass.som @@ -0,0 +1,26 @@ +" + +$Id: Metaclass.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Metaclass = Class ( ) \ No newline at end of file diff --git a/Smalltalk/Method.som b/Smalltalk/Method.som new file mode 100644 index 0000000..b60aaa1 --- /dev/null +++ b/Smalltalk/Method.som @@ -0,0 +1,37 @@ +" + +$Id: Method.som 224 2008-04-21 12:03:47Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Method = ( + + | signature holder numberOfLocals maximumNumberOfStackElements | + + "Meta Information" + signature = ( ^signature ) + holder = ( ^holder ) + + "Printing" + asString = ( ^holder asString + '>>' + signature asString ) + +) diff --git a/Smalltalk/Nil.som b/Smalltalk/Nil.som new file mode 100644 index 0000000..29913df --- /dev/null +++ b/Smalltalk/Nil.som @@ -0,0 +1,34 @@ +" + +$Id: Nil.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Nil = ( + + "Converting" + asString = ( ^'nil' ) + + "Comparing" + isNil = ( ^true ) + +) diff --git a/Smalltalk/Object.som b/Smalltalk/Object.som new file mode 100644 index 0000000..df6d2b7 --- /dev/null +++ b/Smalltalk/Object.som @@ -0,0 +1,90 @@ +" + +$Id: Object.som 225 2008-04-21 12:23:00Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Object = nil ( + + | class | + + "Accessing" + class = ( ^class ) + + "Primitive size in bytes" + objectSize = primitive + + "Comparing" + = other = ( ^self == other ) + <> argument = ( ^(self = argument) not ) + == other = primitive + isNil = ( ^false ) + " If you override =, you MUST override hashcode as well. The rule + obj1 = obj2 => obj1 hashcode = obj2 hashcode + must be valid for all objects, or Hashtable will not work" + + "Converting" + asString = ( ^'instance of ' + (self class) ) + , element = ( ^(Vector new append: self) append: element ) + hashcode = primitive + + "Evaluating" + value = ( ^self ) + + "Printing" + print = ( self asString print ) + println = ( self print. system printNewline ) + + "Error handling" + error: string = ( '' println. ('ERROR: ' + string) println. system exit ) + + "Abstract method support" + subclassResponsibility = ( + self error: 'This method is abstract and should be overridden' + ) + + "Error recovering" + doesNotUnderstand: selector arguments: arguments = ( + self error: + ('Method ' + selector + ' not found in class ' + class name) + ) + + escapedBlock: block = ( + self error: 'Block has escaped and cannot be executed' + ) + + unknownGlobal: name = ( ^system resolve: name ) + + "Reflection" + respondsTo: aSymbol = ( + (self class hasMethod: aSymbol) + ifTrue: [ ^true ] + ifFalse: [ | cls | + cls := self class superclass. + [ cls isNil ] whileFalse: [ + (cls hasMethod: aSymbol) + ifTrue: [ ^true ] + ifFalse: [ cls := cls superclass ] ]. + ^ false ] + ) + +) \ No newline at end of file diff --git a/Smalltalk/Pair.som b/Smalltalk/Pair.som new file mode 100644 index 0000000..41049cf --- /dev/null +++ b/Smalltalk/Pair.som @@ -0,0 +1,51 @@ +" + +$Id: Pair.som 111 2007-09-18 09:21:40Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Pair = ( + + | key value | + + key = ( ^key ) + value = ( ^value ) + + "Private" + key: aKey = ( key := aKey ) + value: aValue = ( value := aValue ) + + "Printing" + print = ( '[' print. key print. '=>' print. value print. ']' print ) + println = ( self print. '' println ) + + ---- + + withKey: aKey andValue: aValue = ( + | newPair | + newPair := super new. + newPair key: aKey. + newPair value: aValue. + ^newPair + ) + +) diff --git a/Smalltalk/Primitive.som b/Smalltalk/Primitive.som new file mode 100644 index 0000000..c9841c9 --- /dev/null +++ b/Smalltalk/Primitive.som @@ -0,0 +1,33 @@ +" + +$Id: Primitive.som 225 2008-04-21 12:23:00Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Primitive = ( + + | signature holder | + + signature = ( ^signature ) + holder = ( ^holder ) + +) \ No newline at end of file diff --git a/Smalltalk/Set.som b/Smalltalk/Set.som new file mode 100644 index 0000000..ea4a4f3 --- /dev/null +++ b/Smalltalk/Set.som @@ -0,0 +1,72 @@ +" + +$Id: Set.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Set = ( + + | items | + + add: anObject = ( + (self contains: anObject) + ifFalse: [ items append: anObject ] + ) + + contains: anObject = ( + items do: [ :it | it == anObject ifTrue: [ ^true ] ]. + ^false + ) + + remove: anObject = ( + | newItems | + newItems := Vector new. + [ items isEmpty ] + whileFalse: [ | it | + it := items remove. + it = anObject ifFalse: [ newItems append: it ] ]. + items := newItems + ) + + "Iteration" + do: block = ( items do: block ) + + "Printing" + println = ( + '(' print. + self do: [ :it | '(' print. it print. ')' print ]. + ')' println + ) + + "Private" + items: it = ( items := it ) + + ---- + + new = ( + | newSet | + newSet := super new. + newSet items: Vector new. + ^newSet + ) + +) diff --git a/Smalltalk/String.som b/Smalltalk/String.som new file mode 100644 index 0000000..165091d --- /dev/null +++ b/Smalltalk/String.som @@ -0,0 +1,61 @@ +" + +$Id: String.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +String = ( + + "Concatenating" + concatenate: argument = primitive + + argument = ( ^self concatenate: argument asString ) + + "Converting" + asString = ( ^self ) + asSymbol = primitive + hashcode = primitive + + "Info" + length = primitive + + "Comparing" + = argument = primitive + + "substring: from 'start' to (and including) 'end'. First character is at + position 0." + primSubstringFrom: start To: end = primitive + + substringFrom: start To: end = ( + ((end < self length) && (start >= 0) && (start <= end)) + ifTrue: [^self primSubstringFrom: start To: end] + ifFalse: [ + self error: 'Attempting to index string out of its bounds.' ] + ) + + charAt: argument = ( + ^self substringFrom: argument To: argument + ) + + "Printing" + print = ( system printString: self ) + +) diff --git a/Smalltalk/Symbol.som b/Smalltalk/Symbol.som new file mode 100644 index 0000000..7cf2d43 --- /dev/null +++ b/Smalltalk/Symbol.som @@ -0,0 +1,35 @@ +" + +$Id: Symbol.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Symbol = ( + + "Converting" + asString = primitive + asSymbol = ( ^self ) + + "Printing" + print = ( '#' print. super print ) + +) \ No newline at end of file diff --git a/Smalltalk/System.som b/Smalltalk/System.som new file mode 100644 index 0000000..9dfc619 --- /dev/null +++ b/Smalltalk/System.som @@ -0,0 +1,89 @@ +" + +$Id: System.som 226 2008-04-21 12:45:01Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +System = ( + + "Accessing" + global: name = primitive + global: name put: value = primitive + + "Initializing" + initialize: arguments = ( + | application | + + "Make sure we have got at least one argument" + (arguments length < 1) ifTrue: [ 'No class specified' println. ^nil ]. + + "Load the class with the specified name, create an instance of it, and + run it. If there is more than only the class given on the command line, + and the class has a method #run:, the arguments array is passed to it, + otherwise, #run is sent." + application := (self resolve: (arguments at: 1) asSymbol) new. + + (arguments length > 1) && (application class hasMethod: #run:) + ifTrue: [ application run: arguments ] + ifFalse: [ application run ] + ) + + "Loading and resolving" + load: symbol = primitive + resolve: symbol = ( + | class current_class | + + "Check if we've already got the global" + (self global: symbol) == nil ifFalse: [ ^self global: symbol ]. + + "Try loading the class" + class := self load: symbol. + (class == nil) ifFalse: [ + "Put class and its super-classes into global dictionary. We can stop + as soon as we find a super-class in the globals dictionary because + in this case, all its super-classes must have been added to the + dictionary earlier" + current_class := class. + [ (self global: (current_class name)) == nil ] whileTrue: [ + self global: (current_class name) put: current_class. + current_class := current_class superclass. ]. + ^class ]. + self error: 'Unable to resolve ' + symbol + ) + + "Exiting" + exit: error = primitive + exit = ( self exit: 0 ) + + "Printing" + printString: string = primitive + printNewline = primitive + + "Time" + time = primitive + + ---------------------------------- + + "Allocation" + new = ( self error: 'The system object is singular' ) + +) diff --git a/Smalltalk/Test.som b/Smalltalk/Test.som new file mode 100644 index 0000000..4573f50 --- /dev/null +++ b/Smalltalk/Test.som @@ -0,0 +1,365 @@ +" + +$Id: All.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +Test = ( + + run = ( + 'Testing...' println. + self hashTest. + self preliminaryTest. + self arrayTest. + self integerTest. + self bigIntegerTest. + self doubleTest. + self coertionTest. + self objectSizeTest. + self symbolTest. + self selfBlockTest. + self reflectionTest. + self closureTest. + 'Tests over.' println + ) + + hashTest = ( + | ht string array t | + ht := Hashtable new. + ht isEmpty + ifFalse: [ 'New Hashtable not empty!' println ]. + ht at: 'a' put: 'b'. + (ht containsValue: 'b') + ifFalse: [ '1 not in Hashtable' println ]. + ht isEmpty + ifTrue: [ 'Nonempty Hashtable empty!' println ]. + ((ht size) = 1) + ifFalse: [ + 'Hashtable has wrong size!' println ]. + + ht at: 'c' put: 'd'. + ((ht size) = 2) + ifFalse: [ + 'Hashtable has wrong size!' println ]. + + ht at: 1 put: 2. + t := Hashtable new. + ht at: Hashtable put: t. + (ht containsValue: 'b') + ifFalse: [ '1 not in Hashtable' println ]. + (ht containsValue: 'd') + ifFalse: [ '2 not in Hashtable' println ]. + (ht containsValue: 2) + ifFalse: [ '3 not in Hashtable' println ]. + (ht containsValue: t) + ifFalse: [ '4 not in Hashtable' println ]. + (ht containsKey: Hashtable) + ifFalse: [ 'key not found' println ]. + + ht clear. + ht isEmpty + ifFalse: [ + 'cleared hashtable is not empty!' println ]. + ht size = 0 + ifFalse: [ + 'cleared hashtable has elements!' println ]. + + string := (ht get: 'a'). + (string = 'b') + ifTrue: [ 'get from Hashtable' println ]. + ) + + doubleTest = ( + ((4/3) + (4/5)) asString = '1' + ifFalse: [ + 'integer division incorrect' println. system exit ]. + ((4//3) + (4//5)) asString = '2.1333333333333333' + ifFalse: [ 'double division incorrect.' println. system exit ]. + ) + + bigIntegerTest = (| bi i a | + + "bi contains 2147483648 - the smallest BigInteger value" + "i contains 2147483647 - the largest Integer value" + + "Test that normal integers work" + a := 2147483646. + a asString = '2147483646' + ifFalse: [ + 'failed to assign to integer' println. system exit ]. + a class asString = 'Integer' + ifFalse: [ + 'failed to create Integer variable' println. system exit ]. + a := a + 1. + a asString = '2147483647' + ifFalse: [ 'failed to add to integer' println. system exit ]. + a class asString = 'Integer' + ifFalse: [ + 'addition caused undue conversion to something other than Integer' println. system exit ]. + + " Store the Integer in i" + i := a. + + " ------------------------- Addition --------------------------------- " + "Test conversion from Integer to BigInteger" + a := a + 1. + a asString = '2147483648' + ifFalse: [ + 'addition exceeding range of Integer failed' println. system exit ]. + a class asString = 'BigInteger' + ifFalse: [ + 'addition exceeding range of Integer caused conversion to something other than BigInteger' println. system exit ]. + + " Store the BigInteger in bi" + bi := a. + + "Test conversion from BigInteger to Integer" + a := a + (-1). + a asString = '2147483647' + ifFalse: [ + 'addition into range of Integer failed' println. system exit ]. + a class asString = 'Integer' + ifFalse: [ + 'warning: addition into range of Integer did not cause conversion to Integer' println ]. + + " ------------------------- Subtraction ------------------------------ " + "Test conversion from Integer to BigInteger" + a := i - (-1). + a asString = '2147483648' + ifFalse: [ + 'subtraction exceeding range of Integer failed' println. system exit ]. + a class asString = 'BigInteger' + ifFalse: [ + 'subtraction exceeding range of Integer caused conversion to something other than BigInteger' println. system exit ]. + + "Test conversion from BigInteger to Integer" + a := a - 1. + a asString = '2147483647' + ifFalse: [ + 'subtraction into range of Integer failed' println. system exit ]. + a class asString = 'Integer' + ifFalse: [ + 'warning: subtraction into range of Integer did not cause conversion to Integer' println ]. + + " ------------------------- Multiplication --------------------------- " + "Test conversion from Integer to BigInteger" + a := i * 2. + a asString = '4294967294' + ifFalse: [ + 'multiplication exceeding range of Integer failed' println. system exit ]. + a class asString = 'BigInteger' + ifFalse: [ + 'multiplication exceeding range of Integer caused conversion to something other than BigInteger' println. system exit ]. + + "Test conversion from BigInteger to Integer" + a := a * 0. + a asString = '0' + ifFalse: [ + 'multiplication into range of Integer failed' println. system exit ]. + a class asString = 'Integer' + ifFalse: [ + 'multiplication into range of Integer did not cause conversion to Integer' println. system exit ]. + + " ------------------------- Division --------------------------------- " + "Test conversion from Integer to BigInteger - TODO requires doubles + a := i / 2. + a asString = '4294967294' + ifFalse: [ + 'division exceeding range of Integer failed' println. system exit ]. + a class asString = 'BigInteger' + ifFalse: [ + 'division exceeding range of Integer caused conversion to something other than BigInteger' println. system exit ]. + " + + "Test conversion from BigInteger to Integer" + a := bi / 2. + a asString = '1073741824' + ifFalse: [ + 'division into range of Integer failed' println. system exit ]. + a class asString = 'Integer' + ifFalse: [ + 'division into range of Integer did not cause conversion to Integer' println. system exit ]. + + "Canonic values" + a := bi. + i := bi. + a = i ifFalse: [ 'equality check failed' println. system exit ]. + a == i ifFalse: [ 'identity check failed' println. system exit ]. + + ) + + arrayTest = ( + | a | + a := Array new: 3. + a at: 1 put: 'hello'. + a at: 2 put: #world. + a at: 3 put: 23. + + (a length = 3) + ifFalse: [ + 'length is ' print. + a length println. + system exit + ]. + (a at: 2) = #world ifFalse: [ + 'Element at 2 should be #world.' println. + system exit + ]. + (a at: 3) = 23 ifFalse: [ + 'Element at 3 should be 23.' println. + system exit + ]. + (a contains: 23) ifFalse: [ + 'Containment check for 23 should be true.' println. + system exit + ]. + + ) + + integerTest = ( + | a b | + a := 42. + b := 42. + a = b ifFalse: [ + '42 and 42 are not equal' println. + system exit]. + a == b ifFalse: [ + '42 and 42 are not identical' println]. + ) + + closureTest = ( + | factorial result facs | + facs := Array new: 10. + facs at: 1 put: 1. + facs at: 2 put: 2. + facs at: 3 put: 6. + facs at: 4 put: 24. + facs at: 5 put: 120. + facs at: 6 put: 720. + facs at: 7 put: 5040. + facs at: 8 put: 40320. + facs at: 9 put: 362880. + facs at: 10 put: 3628800. + factorial := [ :n | + n = 1 + ifTrue: [ 1 ] + ifFalse: [ (factorial value: n - 1) * n ] ]. + result := (1 to: 10) collect: factorial. + result doIndexes: [ :i | + (result at: i) = (facs at: i) ifFalse: [ + 'incorrect result' println. system exit ] ]. + ) + + coertionTest = ( + 25 sqrt = 5 ifFalse: [ + '25 sqrt should be equal to 5.' println. + system exit ]. + (2 // 4) * 2 = 1 ifFalse: [ + '(2//4)*2 should be equal to 1.' println. + system exit ]. + 2 * (2 // 4) = 1 ifFalse: [ + '2*(2//4) should be equal to 1.' println. + system exit ]. + ) + + objectSizeTest = ( + + (Object new objectSize) println. + (42 objectSize) println. + ('hello' objectSize) println. + (Array new objectSize) println. + ((Array new: 1) objectSize) println. + Object new objectSize / 4 = 6 + ifFalse: [ + 'Plain object does not have size 6.' println. system exit ]. + 42 objectSize / 4 = 7 + ifFalse: [ + 'Integer object does not have size 7.' println. system exit ]. + 'hello' objectSize / 4 = 8 + ifFalse: [ + 'String object does not have size 8.' println. system exit ]. + Array new objectSize / 4 = 7 + ifFalse: [ + 'Empty array object does not have size 7.' println. system exit ]. + (Array new: 1) objectSize / 4 = 8 + ifFalse: [ + 'Array object (length 1) does not have size 8.' println. system exit ]. + ) + + preliminaryTest = ( + | a sum | + sum := 0. + + 1, 2, 3 do: [ :i | + sum := sum + i. + i<2 ifTrue: [ sum := sum*2 ]. + i>2 ifFalse: [ sum := sum*2 ] ]. + sum = 15 ifFalse: [ 'Preliminary failed' println. system exit ] + ) + + symbolTest = ( + 'gunk' asSymbol asString = 'gunk' + ifFalse: [ + 'Conversion from string to symbol and back failed' println. system exit ]. + #oink asString = 'oink' + ifFalse: [ + 'Symbol #oink does not evaluate to String oink' println. system exit ]. + ) + + selfBlockTest = ( + self give42 value = 42 + ifFalse: [ + 'access to self in block failed' println. system exit ]. + ) + +"SelfBlockTest methods" + give42 = ( + ^[ self giveBlock value ] + ) + + giveBlock = ( + ^self test value + ) + + test = ( + ^[ self test2 value ] + ) + + test2 = ( + ^[ 42 ] + ) + + reflectionTest = ( + (Object methods at: 1) signature = #class ifFalse: [ + 'The first method in Object is not #class.' println. system exit ]. + (Object hasMethod: #==) ifFalse: [ + 'Object should have the method #==.' println. system exit ]. + (Object new respondsTo: #isNil) ifFalse: [ + 'An Object instance should respond to #isNil.' println. system exit ]. + (23 respondsTo: #isNil) ifFalse: [ + 'Any object should respond to #isNil (even 23).' println. system exit ]. + (23 respondsTo: #+) ifFalse: [ + '23 should respond to #+.' println. system exit ]. + ) + + +) diff --git a/Smalltalk/True.som b/Smalltalk/True.som new file mode 100644 index 0000000..a8a5194 --- /dev/null +++ b/Smalltalk/True.som @@ -0,0 +1,40 @@ +" + +$Id: True.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +True = Boolean ( + + "Converting" + asString = ( ^'true' ) + + "Conditional evaluation" + ifTrue: block = ( ^block value ) + ifFalse: block = ( ^nil ) + + "Logical operations" + not = ( ^false ) + or: block = ( ^true ) + and: block = ( ^block value ) + +) diff --git a/Smalltalk/Vector.som b/Smalltalk/Vector.som new file mode 100644 index 0000000..2537528 --- /dev/null +++ b/Smalltalk/Vector.som @@ -0,0 +1,107 @@ +" + +$Id: Vector.som 223 2008-04-21 11:48:41Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +"FIXME: Implement pushFront and popFront..." + +Vector = ( + + | first last storage | + + "Accessing" + at: index = ( self checkIndex: index ifValid: [ ^storage at: index ] ) + + at: index put: value = ( + self checkIndex: index ifValid: [ ^storage at: index put: value ] + ) + + "Iterating" + do: block = ( + self doIndexes: [ :i | block value: (self at: i) ] + ) + + doIndexes: block = ( + | i | + i := first. + [ i < last ] whileTrue: [ block value: i. i := i + 1 ] + ) + + "Adding" + , element = ( ^self append: element ) + + append: element = ( + (last >= storage length) ifTrue: [ + "Need to expand capacity first" + | newStorage | + newStorage := Array new: (2 * storage length). + storage doIndexes: [ :i | newStorage at: i put: (storage at: i) ]. + storage := newStorage. ]. + + storage at: last put: element. + last := last + 1. + ^self + ) + + "Removing" + remove = ( + (last > first) + ifTrue: [ last := last - 1. ^storage at: last ] + ifFalse: [ + self error: + 'Vector: Attempting to pop element from empty Vector' ] + ) + + "Sizing" + isEmpty = ( ^last = first ) + size = ( ^last - first ) + capacity = ( ^storage length ) + + "Private" + last: integer = ( last := integer ) + first: integer = ( first := integer ) + storage: array = ( storage := array ) + + checkIndex: index ifValid: block = ( + (first <= index) && (index <= last) + ifTrue: [ ^block value ] + ifFalse: [ + self error: + 'Vector[' + first asString + '..' + last asString + + ']: Index ' + index asString + ' out of bounds' ] + ) + + ---------------------------- + + "Allocation" + new = ( ^self new: 50 ) + new: initialSize = ( + | newVector | + newVector := super new. + newVector storage: (Array new: initialSize). + newVector first: 1. + newVector last: 1. + ^newVector + ) + +) diff --git a/TestSuite/ArrayTest.som b/TestSuite/ArrayTest.som new file mode 100644 index 0000000..c5dd0df --- /dev/null +++ b/TestSuite/ArrayTest.som @@ -0,0 +1,55 @@ +" + +$Id: ArrayTest.som 223 2008-04-21 11:48:41Z michael.haupt $ + +Copyright (c) 2007 Michael Haupt, Tobias Pape +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +ArrayTest = ( + run: harness = ( + + | a | + a := Array new: 3. + a at: 1 put: 'hello'. + a at: 2 put: #world. + a at: 3 put: 23. + + a length = 3 ifFalse: [ + harness + fail: self + because: 'Error in array length (should be 3).' ]. + (a at: 2) = #world ifFalse: [ + harness + fail: self + because: 'Element at 2 should be #world.' ]. + (a at: 3) = 23 ifFalse: [ + harness + fail: self + because: 'Element at 3 should be 23.' ]. + (a contains: 23) ifFalse: [ + harness + fail: self + because: 'Containment check for 23 should be true.' ] + + ) +) diff --git a/TestSuite/BigIntegerTest.som b/TestSuite/BigIntegerTest.som new file mode 100644 index 0000000..c709452 --- /dev/null +++ b/TestSuite/BigIntegerTest.som @@ -0,0 +1,177 @@ +" + +$Id: BigIntegerTest.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +BigIntegerTest = ( + + "The 'run' method is called by the testing harness with the harness as its + argument" + + run: harness = (| bi i a | + + "bi contains 2147483648 - the smallest BigInteger value" + "i contains 2147483647 - the largest Integer value" + + "Test that normal integers work" + a := 2147483646. + a asString = '2147483646' + ifFalse: [ + harness fail: self because: 'failed to assign to integer' ]. + a class asString = 'Integer' + ifFalse: [ + harness + fail: self + because: 'failed to create Integer variable' ]. + a := a + 1. + a asString = '2147483647' + ifFalse: [ harness fail: self because: 'failed to add to integer' ]. + a class asString = 'Integer' + ifFalse: [ + harness + fail: self + because: 'addition caused undue conversion to something other than Integer' ]. + + " Store the Integer in i" + i := a. + + " ------------------------- Addition --------------------------------- " + "Test conversion from Integer to BigInteger" + a := a + 1. + a asString = '2147483648' + ifFalse: [ + harness + fail: self + because: 'addition exceeding range of Integer failed' ]. + a class asString = 'BigInteger' + ifFalse: [ + harness + fail: self + because: 'addition exceeding range of Integer caused conversion to something other than BigInteger' ]. + + " Store the BigInteger in bi" + bi := a. + + "Test conversion from BigInteger to Integer" + a := a + (-1). + a asString = '2147483647' + ifFalse: [ + harness + fail: self + because: 'addition into range of Integer failed' ]. + a class asString = 'Integer' + ifFalse: [ + harness + warn: self + because: 'addition into range of Integer did not cause conversion to Integer' ]. + + " ------------------------- Subtraction ------------------------------ " + "Test conversion from Integer to BigInteger" + a := i - (-1). + a asString = '2147483648' + ifFalse: [ + harness + fail: self + because: 'subtraction exceeding range of Integer failed' ]. + a class asString = 'BigInteger' + ifFalse: [ + harness + fail: self + because: 'subtraction exceeding range of Integer caused conversion to something other than BigInteger' ]. + + "Test conversion from BigInteger to Integer" + a := a - 1. + a asString = '2147483647' + ifFalse: [ + harness + fail: self + because: 'subtraction into range of Integer failed' ]. + a class asString = 'Integer' + ifFalse: [ + harness + warn: self + because: 'subtraction into range of Integer did not cause conversion to Integer' ]. + + " ------------------------- Multiplication --------------------------- " + "Test conversion from Integer to BigInteger" + a := i * 2. + a asString = '4294967294' + ifFalse: [ + harness + fail: self + because: 'multiplication exceeding range of Integer failed' ]. + a class asString = 'BigInteger' + ifFalse: [ + harness + fail: self + because: 'multiplication exceeding range of Integer caused conversion to something other than BigInteger' ]. + + "Test conversion from BigInteger to Integer" + a := a * 0. + a asString = '0' + ifFalse: [ + harness + fail: self + because: 'multiplication into range of Integer failed' ]. + a class asString = 'Integer' + ifFalse: [ + harness + warn: self + because: 'multiplication into range of Integer did not cause conversion to Integer' ]. + + " ------------------------- Division --------------------------------- " + "Test conversion from Integer to BigInteger - TODO requires doubles + a := i / 2. + a asString = '4294967294' + ifFalse: [ + harness + fail: self + because: 'division exceeding range of Integer failed' ]. + a class asString = 'BigInteger' + ifFalse: [ + harness + fail: self + because: 'division exceeding range of Integer caused conversion to something other than BigInteger' ]. + " + + "Test conversion from BigInteger to Integer" + a := bi / 2. + a asString = '1073741824' + ifFalse: [ + harness + fail: self + because: 'division into range of Integer failed' ]. + a class asString = 'Integer' + ifFalse: [ + harness + warn: self + because: 'division into range of Integer did not cause conversion to Integer' ]. + + "Canonic values" + a := bi. + i := bi. + a = i ifFalse: [ harness fail: self because: 'equality check failed' ]. + a == i ifFalse: [ harness fail: self because: 'identity check failed' ]. + ) + +) diff --git a/TestSuite/ClosureTest.som b/TestSuite/ClosureTest.som new file mode 100644 index 0000000..7ab3dcc --- /dev/null +++ b/TestSuite/ClosureTest.som @@ -0,0 +1,54 @@ +" + +$Id: ClosureTest.som 663 2008-06-17 10:33:01Z michael.haupt $ + +Copyright (c) 2001-2008 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +"This test verifies that CSOM blocks are indeed closures. The test was found in +Eliot Miranda's Cog Blog." + +ClosureTest = ( + run: harness = ( + | factorial result facs | + facs := Array new: 10. + facs at: 1 put: 1. + facs at: 2 put: 2. + facs at: 3 put: 6. + facs at: 4 put: 24. + facs at: 5 put: 120. + facs at: 6 put: 720. + facs at: 7 put: 5040. + facs at: 8 put: 40320. + facs at: 9 put: 362880. + facs at: 10 put: 3628800. + factorial := [ :n | + n = 1 + ifTrue: [ 1 ] + ifFalse: [ (factorial value: n - 1) * n ] ]. + result := (1 to: 10) collect: factorial. + result doIndexes: [ :i | + (result at: i) = (facs at: i) ifFalse: [ + harness + fail: self + because: 'incorrect result' ] ] + ) +) diff --git a/TestSuite/CoercionTest.som b/TestSuite/CoercionTest.som new file mode 100644 index 0000000..c3c6f17 --- /dev/null +++ b/TestSuite/CoercionTest.som @@ -0,0 +1,45 @@ +" + +$Id: CoercionTest.som 249 2008-04-28 08:17:23Z michael.haupt $ + +Copyright (c) 2007 Michael Haupt, Tobias Pape +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +CoercionTest = ( + + run: harness = ( + 25 sqrt = 5 ifFalse: [ + harness + fail: self + because: '25 sqrt should be equal to 5.' ]. + (2 // 4) * 2 = 1 ifFalse: [ + harness + fail: self + because: '(2//4)*2 should be equal to 1.' ]. + 2 * (2 // 4) = 1 ifFalse: [ + harness + fail: self + because: '2*(2//4) should be equal to 1.' ] + ) + +) diff --git a/TestSuite/DoubleTest.som b/TestSuite/DoubleTest.som new file mode 100644 index 0000000..a83359f --- /dev/null +++ b/TestSuite/DoubleTest.som @@ -0,0 +1,39 @@ +" + +$Id: DoubleTest.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +DoubleTest = ( + + "The 'run' method is called by the testing harness with the harness as its + argument" + + run: harness = ( + ((4/3) + (4/5)) asString = '1' + ifFalse: [ + harness fail: self because: 'integer division incorrect' ]. + ((4//3) + (4//5)) asString = '2.1333333333333333' + ifFalse: [ harness fail: self because: 'double division incorrect' ] + ) + +) diff --git a/TestSuite/EmptyTest.som b/TestSuite/EmptyTest.som new file mode 100644 index 0000000..2ebbfe2 --- /dev/null +++ b/TestSuite/EmptyTest.som @@ -0,0 +1,35 @@ +" + +$Id: EmptyTest.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +EmptyTest = ( + + "The 'run' method is called by the testing harness with the harness as its + argument" + + run: harness = ( + ^self + ) + +) diff --git a/TestSuite/HashTest.som b/TestSuite/HashTest.som new file mode 100644 index 0000000..95fb5b5 --- /dev/null +++ b/TestSuite/HashTest.som @@ -0,0 +1,80 @@ +" + +$Id: HashTest.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +HashTest = ( + + "The 'run' method is called by the testing harness with the harness as its + argument" + + run: harness = ( + | ht string array t | + + ht := Hashtable new. + ht isEmpty + ifFalse: [ harness fail: self because: 'New Hashtable not empty!' ]. + + ht at: 'a' put: 'b'. + (ht containsValue: 'b') + ifFalse: [ harness fail: self because: '1 not in Hashtable' ]. + ht isEmpty + ifTrue: [ harness fail: self because: 'Nonempty Hashtable empty!' ]. + ((ht size) = 1) + ifFalse: [ + harness fail: self because: 'Hashtable has wrong size!' ]. + + ht at: 'c' put: 'd'. + ((ht size) = 2) + ifFalse: [ + harness fail: self because: 'Hashtable has wrong size!' ]. + + ht at: 1 put: 2. + t := Hashtable new. + ht at: Hashtable put: t. + (ht containsValue: 'b') + ifFalse: [ harness fail: self because: '1 not in Hashtable' ]. + (ht containsValue: 'd') + ifFalse: [ harness fail: self because: '2 not in Hashtable' ]. + (ht containsValue: 2) + ifFalse: [ harness fail: self because: '3 not in Hashtable' ]. + (ht containsValue: t) + ifFalse: [ harness fail: self because: '4 not in Hashtable' ]. + (ht containsKey: Hashtable) + ifFalse: [ harness fail: self because: 'key not found' ]. + + ht clear. + ht isEmpty + ifFalse: [ + harness fail: self because: 'cleared hashtable is not empty!' ]. + ht size = 0 + ifFalse: [ + harness fail: self because: 'cleared hashtable has elements!' ]. + + string := (ht get: 'a'). + (string = 'b') + ifTrue: [ harness fail: self because: 'get from Hashtable' ]. + ) + +) + diff --git a/TestSuite/IntegerTest.som b/TestSuite/IntegerTest.som new file mode 100644 index 0000000..0432074 --- /dev/null +++ b/TestSuite/IntegerTest.som @@ -0,0 +1,40 @@ +" + +$Id: IntegerTest.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2007 Michael Haupt, Tobias Pape +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +IntegerTest = ( + + run: harness = ( + | a b | + a := 42. + b := 42. + a = b ifFalse: [ + harness fail: self because: '42 and 42 are not equal' ]. + a == b ifFalse: [ + harness fail: self because: '42 and 42 are not identical' ] + ) + +) diff --git a/TestSuite/ObjectSizeTest.som b/TestSuite/ObjectSizeTest.som new file mode 100644 index 0000000..cc8dbc5 --- /dev/null +++ b/TestSuite/ObjectSizeTest.som @@ -0,0 +1,58 @@ +" + +$Id: ObjectSizeTest.som 210 2008-04-16 12:54:12Z michael.haupt $ + +Copyright (c) 2007 Michael Haupt, Tobias Pape +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +ObjectSizeTest = ( + + run: harness = ( + Object new objectSize / 4 = 6 + ifFalse: [ + harness + fail: self + because: 'Plain object does not have size 6.' ]. + 42 objectSize / 4 = 7 + ifFalse: [ + harness + fail: self + because: 'Integer object does not have size 7.' ]. + 'hello' objectSize / 4 = 9 + ifFalse: [ + harness + fail: self + because: 'hello String object does not have size 9.' ]. + Array new objectSize / 4 = 6 + ifFalse: [ + harness + fail: self + because: 'Empty array object does not have size 7.' ]. + (Array new: 4) objectSize / 4 = 10 + ifFalse: [ + harness + fail: self + because: 'Array object (length 4) does not have size 11.' ]. + ) + +) \ No newline at end of file diff --git a/TestSuite/PreliminaryTest.som b/TestSuite/PreliminaryTest.som new file mode 100644 index 0000000..996d2df --- /dev/null +++ b/TestSuite/PreliminaryTest.som @@ -0,0 +1,45 @@ +" + +$Id: PreliminaryTest.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +"... something just a bit complicated that tests iteration with +blocks, so that we might fail here rather than when the other tests +start, in case things are broken." + +PreliminaryTest = ( + + "The 'run' method is called by the testing harness with the harness as its + argument" + + run: harness = ( + | sum | + sum := 0. + 1, 2, 3 do: [ :i | + sum := sum + i. + i<2 ifTrue: [ sum := sum*2 ]. + i>2 ifFalse: [ sum := sum*2 ] ]. + sum = 15 ifFalse: [ harness fail: self ] + ) + +) diff --git a/TestSuite/ReflectionTest.som b/TestSuite/ReflectionTest.som new file mode 100644 index 0000000..4840766 --- /dev/null +++ b/TestSuite/ReflectionTest.som @@ -0,0 +1,51 @@ +" + +$Id: ReflectionTest.som 225 2008-04-21 12:23:00Z michael.haupt $ + +Copyright (c) 2007 Michael Haupt, Tobias Pape +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +ReflectionTest = ( + run: harness = ( + (Object methods at: 1) signature = #class ifFalse: [ + harness + fail: self + because: 'The first method in Object is not #class.' ]. + (Object hasMethod: #==) ifFalse: [ + harness + fail: self + because: 'Object should have the method #==.' ]. + (Object new respondsTo: #isNil) ifFalse: [ + harness + fail: self + because: 'An Object instance should respond to #isNil.' ]. + (23 respondsTo: #isNil) ifFalse: [ + harness + fail: self + because: 'Any object should respond to #isNil (even 23).' ]. + (23 respondsTo: #+) ifFalse: [ + harness + fail: self + because: '23 should respond to #+.' ] + ) +) diff --git a/TestSuite/SelfBlockTest.som b/TestSuite/SelfBlockTest.som new file mode 100644 index 0000000..d1daddf --- /dev/null +++ b/TestSuite/SelfBlockTest.som @@ -0,0 +1,53 @@ +" + +$Id: SelfBlockTest.som 111 2007-09-18 09:21:40Z tobias.pape $ + +Copyright (c) 2007 Michael Haupt, Tobias Pape +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +SelfBlockTest = ( + + run: harness = ( + self give42 value = 42 + ifFalse: [ + harness fail: self because: 'access to self in block failed' ]. + ) + + give42 = ( + ^[ self giveBlock value ] + ) + + giveBlock = ( + ^self test value + ) + + test = ( + ^[ self test2 value ] + ) + + test2 = ( + ^[ 42 ] + ) + +) + diff --git a/TestSuite/SuperTest.som b/TestSuite/SuperTest.som new file mode 100644 index 0000000..a25e58d --- /dev/null +++ b/TestSuite/SuperTest.som @@ -0,0 +1,52 @@ +" + +$Id: SuperTest.som 111 2007-09-18 09:21:40Z tobias.pape $ + +Copyright (c) 2007 Michael Haupt, Tobias Pape +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +SuperTest = SuperTestSuperClass ( + + run: harness = ( + self give42 = 42 + ifFalse: [ + harness + fail: self + because: 'Direct send to super did not return 42.' ]. + self blockGive42 = 42 + ifFalse: [ + harness + fail: self + because: 'Send to super from block did not return 42.' ] + ) + + give42 = ( + ^super give42 + ) + + blockGive42 = ( + ^[ super give42 ] value + ) + +) + diff --git a/TestSuite/SuperTestSuperClass.som b/TestSuite/SuperTestSuperClass.som new file mode 100644 index 0000000..28c3b44 --- /dev/null +++ b/TestSuite/SuperTestSuperClass.som @@ -0,0 +1,35 @@ +" + +$Id: SuperTestSuperClass.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2007 Michael Haupt, Tobias Pape +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +SuperTestSuperClass = ( + + give42 = ( + ^42 + ) + +) + diff --git a/TestSuite/SymbolTest.som b/TestSuite/SymbolTest.som new file mode 100644 index 0000000..0e186ab --- /dev/null +++ b/TestSuite/SymbolTest.som @@ -0,0 +1,43 @@ +" + +$Id: SymbolTest.som 92 2007-09-06 09:23:43Z tobias.pape $ + +Copyright (c) 2007 Michael Haupt, Tobias Pape +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +SymbolTest = ( + + run: harness = ( + 'gunk' asSymbol asString = 'gunk' + ifFalse: [ + harness + fail: self + because: 'Conversion from string to symbol and back failed' ]. + #oink asString = 'oink' + ifFalse: [ + harness + fail: self + because: 'Symbol #oink does not evaluate to String oink' ] + ) + +) diff --git a/TestSuite/TestHarness.som b/TestSuite/TestHarness.som new file mode 100644 index 0000000..fcb6430 --- /dev/null +++ b/TestSuite/TestHarness.som @@ -0,0 +1,60 @@ +" + +$Id: TestHarness.som 663 2008-06-17 10:33:01Z michael.haupt $ + +Copyright (c) 2001-2007 see AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +" + +TestHarness = ( + + tests = ( + ^ EmptyTest, DoubleTest, HashTest, SymbolTest, BigIntegerTest, + SuperTest, SelfBlockTest, ObjectSizeTest, ArrayTest, ReflectionTest, + CoercionTest, ClosureTest + ) + + run = ( + 'Testing...' println. + PreliminaryTest new run: self. + self tests do: [ :test | + ('Running test ' + test) println. test new run: self ]. + '...done' println + ) + + fail: who = ( + ('Test ' + who + ' failed!') println. + system exit: 1 + ) + + fail: who because: reason = ( + ('Test ' + who + ' failed: ' + reason) println. + system exit: 1 + ) + + warn: who = ( + ('Warning: Test ' + who + ' failed!') println. + ) + + warn: who because: reason = ( + ('Warning: Test ' + who + ' failed: ' + reason) println. + ) + +) diff --git a/build/Darwin.make b/build/Darwin.make new file mode 100644 index 0000000..a7fca94 --- /dev/null +++ b/build/Darwin.make @@ -0,0 +1,219 @@ +#!/usr/bin/env make -f + +# +# Based on Makefile by Tobias Pape +# +# +# Copyright (c) 2007 Michael Haupt, Tobias Pape +# Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +# http://www.hpi.uni-potsdam.de/swa/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +CC =g++ +CFLAGS =-Wno-endif-labels -O3 $(DBG_FLAGS) $(INCLUDES) +LDFLAGS =$(LIBRARIES) + +SHAREDFLAGS =-fPIC -mmacosx-version-min=10.4 -undefined dynamic_lookup \ + -dynamiclib -Wl,-single_module -Wl,-Y,1455 + +INSTALL =install + +CSOM_LIBS = +CORE_LIBS =-lm + +CSOM_NAME =SOM++ +CORE_NAME =SOMCore +PRIMITIVESCORE_NAME =PrimitiveCore +SHARED_EXTENSION =dll + +############ global stuff -- overridden by ../Makefile + +ROOT_DIR ?= $(PWD)/.. +SRC_DIR ?= $(ROOT_DIR)/src +BUILD_DIR ?= $(ROOT_DIR)/build +DEST_DIR ?= $(ROOT_DIR)/build.out + +ST_DIR ?= $(ROOT_DIR)/Smalltalk +EX_DIR ?= $(ROOT_DIR)/Examples +TEST_DIR ?= $(ROOT_DIR)/TestSuite + +############# "component" directories + + +COMPILER_DIR = $(SRC_DIR)/compiler +INTERPRETER_DIR = $(SRC_DIR)/interpreter +MEMORY_DIR = $(SRC_DIR)/memory +MISC_DIR = $(SRC_DIR)/misc +VM_DIR = $(SRC_DIR)/vm +VMOBJECTS_DIR = $(SRC_DIR)/vmobjects + +COMPILER_SRC = $(wildcard $(COMPILER_DIR)/*.cpp) +COMPILER_OBJ = $(COMPILER_SRC:.cpp=.o) +INTERPRETER_SRC = $(wildcard $(INTERPRETER_DIR)/*.cpp) +INTERPRETER_OBJ = $(INTERPRETER_SRC:.cpp=.o) +MEMORY_SRC = $(wildcard $(MEMORY_DIR)/*.cpp) +MEMORY_OBJ = $(MEMORY_SRC:.cpp=.o) +MISC_SRC = $(wildcard $(MISC_DIR)/*.cpp) +MISC_OBJ = $(MISC_SRC:.cpp=.o) +VM_SRC = $(wildcard $(VM_DIR)/*.cpp) +VM_OBJ = $(VM_SRC:.cpp=.o) +VMOBJECTS_SRC = $(wildcard $(VMOBJECTS_DIR)/*.cpp) +VMOBJECTS_OBJ = $(VMOBJECTS_SRC:.cpp=.o) + +MAIN_SRC = $(wildcard $(SRC_DIR)/*.cpp) +#$(SRC_DIR)/Main.cpp +MAIN_OBJ = $(MAIN_SRC:.cpp=.o) +#$(SRC_DIR)/main.o + +############# primitives loading + +PRIMITIVESCORE_DIR = $(SRC_DIR)/primitivesCore +PRIMITIVESCORE_SRC = $(wildcard $(PRIMITIVESCORE_DIR)/*.cpp) +PRIMITIVESCORE_OBJ = $(PRIMITIVESCORE_SRC:.cpp=.pic.o) + +############# primitives location etc. + +PRIMITIVES_DIR = $(SRC_DIR)/primitives +PRIMITIVES_SRC = $(wildcard $(PRIMITIVES_DIR)/*.cpp) +PRIMITIVES_OBJ = $(PRIMITIVES_SRC:.cpp=.o) + +############# include path + +INCLUDES =-I$(SRC_DIR) +LIBRARIES =-L$(ROOT_DIR) + +############## +############## Collections. + +CSOM_OBJ = $(MEMORY_OBJ) $(MISC_OBJ) $(VMOBJECTS_OBJ) \ + $(COMPILER_OBJ) $(INTERPRETER_OBJ) $(VM_OBJ) + +OBJECTS = $(CSOM_OBJ) $(PRIMITIVESCORE_OBJ) $(PRIMITIVES_OBJ) $(MAIN_OBJ) + +SOURCES = $(COMPILER_SRC) $(INTERPRETER_SRC) $(MEMORY_SRC) \ + $(MISC_SRC) $(VM_SRC) $(VMOBJECTS_SRC) \ + $(PRIMITIVES_SRC) $(PRIMITIVESCORE_SRC) $(MAIN_SRC) + +############# Things to clean + +CLEAN = $(OBJECTS) \ + $(DIST_DIR) $(DEST_DIR) CORE SOM++ +############# Tools + +#OSTOOL = $(BUILD_DIR)/ostool + +# +# +# +# metarules +# + +.SUFFIXES: .pic.o .fpic.o + +.PHONY: clean clobber test + +all: $(CSOM_NAME)\ + $(CSOM_NAME).$(SHARED_EXTENSION) \ + $(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION) \ + CORE + + +debug : DBG_FLAGS=-DDEBUG -g +debug: all + +profiling : DBG_FLAGS=-g -pg +profiling : LDFLAGS+=-pg +profiling: all + + +.cpp.pic.o: + $(CC) $(CFLAGS) -fPIC -c $< -o $*.pic.o + +.cpp.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +clean: + rm -Rf $(CLEAN) + + + +# +# +# +# product rules +# + +$(CSOM_NAME): $(CSOM_NAME).$(SHARED_EXTENSION) $(MAIN_OBJ) + @echo Linking $(CSOM_NAME) loader + $(CC) $(LDFLAGS) \ + -o $(CSOM_NAME) $(MAIN_OBJ) $(CSOM_NAME).$(SHARED_EXTENSION) -ldl + @echo loader done. + +$(CSOM_NAME).$(SHARED_EXTENSION): $(CSOM_OBJ) + @echo Linking $(CSOM_NAME) Dynamic Library + $(CC) $(LDFLAGS) $(SHAREDFLAGS) \ + -o $(CSOM_NAME).$(SHARED_EXTENSION) $(CSOM_OBJ) $(CSOM_LIBS) + @echo CSOM done. + +$(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION): $(CSOM_NAME) $(PRIMITIVESCORE_OBJ) + @echo Linking PrimitivesCore lib + $(CC) $(LDFLAGS) $(SHAREDFLAGS) \ + -o $(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION) \ + $(PRIMITIVESCORE_OBJ) + @touch $(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION) + @echo PrimitivesCore done. + +CORE: $(CSOM_NAME) $(PRIMITIVESCORE_OBJ) $(PRIMITIVES_OBJ) + @echo Linking SOMCore lib + $(CC) $(LDFLAGS) \ + $(SHAREDFLAGS) -o $(CORE_NAME).csp \ + $(PRIMITIVES_OBJ) \ + $(PRIMITIVESCORE_OBJ) \ + $(CORE_LIBS) + mv $(CORE_NAME).csp $(ST_DIR) + @touch CORE + @echo SOMCore done. + +install: all + @echo installing CSOM into build + $(INSTALL) -d $(DEST_DIR) + $(INSTALL) $(CSOM_NAME) $(DEST_DIR) + @echo CSOM. + cp -Rpf $(ST_DIR) $(EX_DIR) $(TEST_DIR) $(DEST_DIR) + @echo Library. + @echo done. + +# +# console: start the console +# +console: all + ./$(CSOM_NAME) -cp ./Smalltalk + +# +# test: run the standard test suite +# +test: all + ./$(CSOM_NAME) -cp ./Smalltalk ./TestSuite/TestHarness.som + +# +# bench: run the benchmarks +# +bench: all + ./$(CSOM_NAME) -cp ./Smalltalk ./Examples/Benchmarks/All.som diff --git a/build/Linux.make b/build/Linux.make new file mode 100644 index 0000000..e2f3895 --- /dev/null +++ b/build/Linux.make @@ -0,0 +1,216 @@ +#!/usr/bin/env make -f + +# +# Based on Makefile by Tobias Pape +# +# +# Copyright (c) 2007 Michael Haupt, Tobias Pape +# Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +# http://www.hpi.uni-potsdam.de/swa/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +CC =g++ +CFLAGS =-Wno-endif-labels -O3 $(DBG_FLAGS) $(INCLUDES) +LDFLAGS =$(LIBRARIES) + +INSTALL =install + +CSOM_LIBS = +CORE_LIBS =-lm + +CSOM_NAME =SOM++ +CORE_NAME =SOMCore +PRIMITIVESCORE_NAME =PrimitiveCore +SHARED_EXTENSION =so + +############ global stuff -- overridden by ../Makefile + +ROOT_DIR ?= $(PWD)/.. +SRC_DIR ?= $(ROOT_DIR)/src +BUILD_DIR ?= $(ROOT_DIR)/build +DEST_DIR ?= $(ROOT_DIR)/build.out + +ST_DIR ?= $(ROOT_DIR)/Smalltalk +EX_DIR ?= $(ROOT_DIR)/Examples +TEST_DIR ?= $(ROOT_DIR)/TestSuite + +############# "component" directories + + +COMPILER_DIR = $(SRC_DIR)/compiler +INTERPRETER_DIR = $(SRC_DIR)/interpreter +MEMORY_DIR = $(SRC_DIR)/memory +MISC_DIR = $(SRC_DIR)/misc +VM_DIR = $(SRC_DIR)/vm +VMOBJECTS_DIR = $(SRC_DIR)/vmobjects + +COMPILER_SRC = $(wildcard $(COMPILER_DIR)/*.cpp) +COMPILER_OBJ = $(COMPILER_SRC:.cpp=.o) +INTERPRETER_SRC = $(wildcard $(INTERPRETER_DIR)/*.cpp) +INTERPRETER_OBJ = $(INTERPRETER_SRC:.cpp=.o) +MEMORY_SRC = $(wildcard $(MEMORY_DIR)/*.cpp) +MEMORY_OBJ = $(MEMORY_SRC:.cpp=.o) +MISC_SRC = $(wildcard $(MISC_DIR)/*.cpp) +MISC_OBJ = $(MISC_SRC:.cpp=.o) +VM_SRC = $(wildcard $(VM_DIR)/*.cpp) +VM_OBJ = $(VM_SRC:.cpp=.o) +VMOBJECTS_SRC = $(wildcard $(VMOBJECTS_DIR)/*.cpp) +VMOBJECTS_OBJ = $(VMOBJECTS_SRC:.cpp=.o) + +MAIN_SRC = $(wildcard $(SRC_DIR)/*.cpp) +#$(SRC_DIR)/Main.cpp +MAIN_OBJ = $(MAIN_SRC:.cpp=.o) +#$(SRC_DIR)/main.o + +############# primitives loading + +PRIMITIVESCORE_DIR = $(SRC_DIR)/primitivesCore +PRIMITIVESCORE_SRC = $(wildcard $(PRIMITIVESCORE_DIR)/*.cpp) +PRIMITIVESCORE_OBJ = $(PRIMITIVESCORE_SRC:.cpp=.pic.o) + +############# primitives location etc. + +PRIMITIVES_DIR = $(SRC_DIR)/primitives +PRIMITIVES_SRC = $(wildcard $(PRIMITIVES_DIR)/*.cpp) +PRIMITIVES_OBJ = $(PRIMITIVES_SRC:.cpp=.pic.o) + +############# include path + +INCLUDES =-I$(SRC_DIR) +LIBRARIES =-L$(ROOT_DIR) + +############## +############## Collections. + +CSOM_OBJ = $(MEMORY_OBJ) $(MISC_OBJ) $(VMOBJECTS_OBJ) \ + $(COMPILER_OBJ) $(INTERPRETER_OBJ) $(VM_OBJ) + +OBJECTS = $(CSOM_OBJ) $(PRIMITIVESCORE_OBJ) $(PRIMITIVES_OBJ) $(MAIN_OBJ) + +SOURCES = $(COMPILER_SRC) $(INTERPRETER_SRC) $(MEMORY_SRC) \ + $(MISC_SRC) $(VM_SRC) $(VMOBJECTS_SRC) \ + $(PRIMITIVES_SRC) $(PRIMITIVESCORE_SRC) $(MAIN_SRC) + +############# Things to clean + +CLEAN = $(OBJECTS) \ + $(DIST_DIR) $(DEST_DIR) CORE +############# Tools + +#OSTOOL = $(BUILD_DIR)/ostool + +# +# +# +# metarules +# + +.SUFFIXES: .pic.o .fpic.o + +.PHONY: clean clobber test + +all: $(CSOM_NAME)\ + $(CSOM_NAME).$(SHARED_EXTENSION) \ + $(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION) \ + CORE + + +debug : DBG_FLAGS=-DDEBUG -g +debug: all + +profiling : DBG_FLAGS=-g -pg +profiling : LDFLAGS+=-pg +profiling: all + + +.cpp.pic.o: + $(CC) $(CFLAGS) -fPIC -c $< -o $*.pic.o + +.cpp.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +clean: + rm -Rf $(CLEAN) + + + +# +# +# +# product rules +# + +$(CSOM_NAME): $(CSOM_NAME).$(SHARED_EXTENSION) $(MAIN_OBJ) + @echo Linking $(CSOM_NAME) loader + $(CC) $(LDFLAGS) \ + -o $(CSOM_NAME) $(MAIN_OBJ) $(CSOM_NAME).$(SHARED_EXTENSION) -ldl + @echo CSOM done. + +$(CSOM_NAME).$(SHARED_EXTENSION): $(CSOM_OBJ) + @echo Linking $(CSOM_NAME) Dynamic Library + $(CC) $(LDFLAGS) -shared \ + -o $(CSOM_NAME).$(SHARED_EXTENSION) $(CSOM_OBJ) $(CSOM_LIBS) + @echo CSOM done. + +$(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION): $(CSOM_NAME) $(PRIMITIVESCORE_OBJ) + @echo Linking PrimitivesCore lib + $(CC) $(LDFLAGS) -shared \ + -o $(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION) \ + $(PRIMITIVESCORE_OBJ) + @touch $(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION) + @echo PrimitivesCore done. + +CORE: $(CSOM_NAME) $(PRIMITIVESCORE_OBJ) $(PRIMITIVES_OBJ) + @echo Linking SOMCore lib + $(CC) $(LDFLAGS) \ + -shared -o $(CORE_NAME).csp \ + $(PRIMITIVES_OBJ) \ + $(PRIMITIVESCORE_OBJ) \ + $(CORE_LIBS) + mv $(CORE_NAME).csp $(ST_DIR) + @touch CORE + @echo SOMCore done. + +install: all + @echo installing CSOM into build + $(INSTALL) -d $(DEST_DIR) + $(INSTALL) $(CSOM_NAME) $(DEST_DIR) + @echo CSOM. + cp -Rpf $(ST_DIR) $(EX_DIR) $(TEST_DIR) $(DEST_DIR) + @echo Library. + @echo done. + +# +# console: start the console +# +console: all + ./$(CSOM_NAME) -cp ./Smalltalk + +# +# test: run the standard test suite +# +test: all + ./$(CSOM_NAME) -cp ./Smalltalk ./TestSuite/TestHarness.som + +# +# bench: run the benchmarks +# +bench: all + ./$(CSOM_NAME) -cp ./Smalltalk ./Examples/Benchmarks/All.som diff --git a/build/windows.make b/build/windows.make new file mode 100644 index 0000000..a331d90 --- /dev/null +++ b/build/windows.make @@ -0,0 +1,231 @@ +#!/usr/bin/env make -f + +# +# Based on Makefile by Tobias Pape +# +# +# Copyright (c) 2007 Michael Haupt, Tobias Pape +# Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +# http://www.hpi.uni-potsdam.de/swa/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +CC =g++ +CFLAGS =-Wno-endif-labels -O3 $(DBG_FLAGS) $(INCLUDES) +LDFLAGS =--enable-auto-import $(LIBRARIES) + +INSTALL =install + +CSOM_LIBS = +CORE_LIBS =-lm + +CSOM_NAME =SOM++ +CORE_NAME =SOMCore +PRIMITIVESCORE_NAME =PrimitiveCore +SHARED_EXTENSION =dll + +############ global stuff -- overridden by ../Makefile + +ROOT_DIR ?= $(PWD)/.. +SRC_DIR ?= $(ROOT_DIR)/src +BUILD_DIR ?= $(ROOT_DIR)/build +DEST_DIR ?= $(ROOT_DIR)/build.out + +ST_DIR ?= $(ROOT_DIR)/Smalltalk +EX_DIR ?= $(ROOT_DIR)/Examples +TEST_DIR ?= $(ROOT_DIR)/TestSuite + +############# "component" directories + + +COMPILER_DIR = $(SRC_DIR)/compiler +INTERPRETER_DIR = $(SRC_DIR)/interpreter +MEMORY_DIR = $(SRC_DIR)/memory +MISC_DIR = $(SRC_DIR)/misc +VM_DIR = $(SRC_DIR)/vm +VMOBJECTS_DIR = $(SRC_DIR)/vmobjects + +COMPILER_SRC = $(wildcard $(COMPILER_DIR)/*.cpp) +COMPILER_OBJ = $(COMPILER_SRC:.cpp=.o) +INTERPRETER_SRC = $(wildcard $(INTERPRETER_DIR)/*.cpp) +INTERPRETER_OBJ = $(INTERPRETER_SRC:.cpp=.o) +MEMORY_SRC = $(wildcard $(MEMORY_DIR)/*.cpp) +MEMORY_OBJ = $(MEMORY_SRC:.cpp=.o) +MISC_SRC = $(wildcard $(MISC_DIR)/*.cpp) +MISC_OBJ = $(MISC_SRC:.cpp=.o) +VM_SRC = $(wildcard $(VM_DIR)/*.cpp) +VM_OBJ = $(VM_SRC:.cpp=.o) +VMOBJECTS_SRC = $(wildcard $(VMOBJECTS_DIR)/*.cpp) +VMOBJECTS_OBJ = $(VMOBJECTS_SRC:.cpp=.o) + +MAIN_SRC = $(wildcard $(SRC_DIR)/*.cpp) +#$(SRC_DIR)/Main.cpp +MAIN_OBJ = $(MAIN_SRC:.cpp=.o) +#$(SRC_DIR)/main.o + +############# snake primitives + +SNAKEPRIMITIVESCORE_DIR = $(ROOT_DIR)/Examples/Snake +SNAKEPRIMITIVESCORE_SRC = $(wildcard $(SNAKEPRIMITIVESCORE_DIR)/*.cpp) +SNAKEPRIMITIVESCORE_OBJ = $(SNAKEPRIMITIVESCORE_SRC:.cpp=.pic.o) + +############# primitives loading + +PRIMITIVESCORE_DIR = $(SRC_DIR)/primitivesCore +PRIMITIVESCORE_SRC = $(wildcard $(PRIMITIVESCORE_DIR)/*.cpp) +PRIMITIVESCORE_OBJ = $(PRIMITIVESCORE_SRC:.cpp=.pic.o) + +############# primitives location etc. + +PRIMITIVES_DIR = $(SRC_DIR)/primitives +PRIMITIVES_SRC = $(wildcard $(PRIMITIVES_DIR)/*.cpp) +PRIMITIVES_OBJ = $(PRIMITIVES_SRC:.cpp=.pic.o) + +############# include path + +INCLUDES =-I$(SRC_DIR) +LIBRARIES =-L$(ROOT_DIR) + +############## +############## Collections. + +CSOM_OBJ = $(MEMORY_OBJ) $(MISC_OBJ) $(VMOBJECTS_OBJ) \ + $(COMPILER_OBJ) $(INTERPRETER_OBJ) $(VM_OBJ) + +OBJECTS = $(CSOM_OBJ) $(PRIMITIVES_OBJ) $(PRIMITIVESCORE_OBJ) $(SNAKEPRIMITIVESCORE_OBJ) $(MAIN_OBJ) + +SOURCES = $(COMPILER_SRC) $(INTERPRETER_SRC) $(MEMORY_SRC) \ + $(MISC_SRC) $(VM_SRC) $(VMOBJECTS_SRC) \ + $(PRIMITIVES_SRC) $(PRIMITIVESCORE_SRC) $(SNAKEPRIMITIVESCORE_SRC) $(MAIN_SRC) + +############# Things to clean + +CLEAN = $(OBJECTS) \ + $(DIST_DIR) $(DEST_DIR) CORE +############# Tools + +#OSTOOL = $(BUILD_DIR)/ostool.exe + +# +# +# +# metarules +# + +.SUFFIXES: .pic.o .fpic.o + +.PHONY: clean clobber test + +all: $(CSOM_NAME).exe \ + $(CSOM_NAME).$(SHARED_EXTENSION) \ + $(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION) \ + CORE + + +debug : DBG_FLAGS=-DDEBUG -g +debug: all + +.cpp.pic.o: + $(CC) $(CFLAGS) -c $< -o $*.pic.o + + +.cpp.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +clean: + rm -Rf $(CLEAN) + + + +# +# +# +# product rules +# + +$(CSOM_NAME).exe: $(CSOM_NAME).$(SHARED_EXTENSION) $(MAIN_OBJ) + @echo Linking $(CSOM_NAME) loader + $(CC) $(LDFLAGS) \ + -o $(CSOM_NAME).exe $(MAIN_OBJ) -l$(CSOM_NAME) + @echo loader done. + +$(CSOM_NAME).$(SHARED_EXTENSION): $(CSOM_OBJ) + @echo Linking $(CSOM_NAME) Dynamic Library + $(CC) $(LDFLAGS) -shared \ + -o $(CSOM_NAME).$(SHARED_EXTENSION) $(CSOM_OBJ) $(CSOM_LIBS) + @echo CSOM done. + +$(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION): $(CSOM_NAME).$(SHARED_EXTENSION) $(PRIMITIVESCORE_OBJ) + @echo Linking PrimitivesCore lib + $(CC) $(LDFLAGS) -shared \ + -o $(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION) \ + $(PRIMITIVESCORE_OBJ) \ + -l$(CSOM_NAME) + @touch $(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION) + @echo PrimitivesCore done. + +CORE: $(PRIMITIVESCORE_NAME).$(SHARED_EXTENSION) $(CSOM_NAME).$(SHARED_EXTENSION) $(PRIMITIVES_OBJ) + @echo Linking SOMCore lib + $(CC) $(LDFLAGS) -shared \ + -o $(CORE_NAME).csp \ + $(PRIMITIVES_OBJ) \ + $(CORE_LIBS) -l$(CSOM_NAME) -l$(PRIMITIVESCORE_NAME) + mv $(CORE_NAME).csp $(ST_DIR) + @touch CORE + @echo SOMCore done. + +SNAKE: $(PRIMITIVESCORE_NAME).dll $(CSOM_NAME).$(SHARED_EXTENSION) $(SNAKEPRIMITIVES_OBJ) + @echo Linking Snake lib + $(CC) $(LDFLAGS) -shared \ + -o $(EX_DIR)/Snake/Terminal.csp \ + $(SNAKEPRIMITIVES_OBJ) \ + $(CORE_LIBS) -l$(CSOM_NAME) -l$(PRIMITIVESCORE_NAME) + @echo Snake done. + +install: all + @echo installing CSOM into build + $(INSTALL) -d $(DEST_DIR) + $(INSTALL) $(CSOM_NAME) $(DEST_DIR) + @echo CSOM. + cp -Rpf $(ST_DIR) $(EX_DIR) $(TEST_DIR) $(DEST_DIR) + @echo Library. + @echo done. +# +# snake: starts snake +# +snake: all SNAKE + ./$(CSOM_NAME).exe -cp Smalltalk Examples/Snake/Main.som + +# +# console: start the console +# +console: all + ./$(CSOM_NAME).exe -cp Smalltalk + +# +# test: run the standard test suite +# +test: all + ./$(CSOM_NAME).exe -g -cp Smalltalk Testsuite/TestHarness.som + +# +# bench: run the benchmarks +# +bench: all + ./$(CSOM_NAME).exe -g -cp Smalltalk Examples/Benchmarks/All.som diff --git a/cppsom.sln b/cppsom.sln new file mode 100644 index 0000000..17687d2 --- /dev/null +++ b/cppsom.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cppsom", "cppsom.vcproj", "{E4C195C8-982E-4690-8C7F-4E4C667542BD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E4C195C8-982E-4690-8C7F-4E4C667542BD}.Debug|Win32.ActiveCfg = Debug|Win32 + {E4C195C8-982E-4690-8C7F-4E4C667542BD}.Debug|Win32.Build.0 = Debug|Win32 + {E4C195C8-982E-4690-8C7F-4E4C667542BD}.Release|Win32.ActiveCfg = Release|Win32 + {E4C195C8-982E-4690-8C7F-4E4C667542BD}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/cppsom.vcproj b/cppsom.vcproj new file mode 100644 index 0000000..6f6a9a9 --- /dev/null +++ b/cppsom.vcproj @@ -0,0 +1,958 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/styleguide.tex b/doc/styleguide.tex new file mode 100644 index 0000000..39f7595 --- /dev/null +++ b/doc/styleguide.tex @@ -0,0 +1,429 @@ +% +% the CPPSOM Style Guide +% +% $Id: styleguide.tex 169 2008-29-10 17:41:48Z arne.bergmann $ +% +\documentclass{scrartcl} +\usepackage{listings} +\begin{document} + +\section{CPPSOM Style Guidelines} +\label{sec:cppsom-style-guid} + +\subsection{Common Rules} +\label{sec:common-rules} +\begin{itemize} +\item A line shall have at most 80 columns. +\item Each file shall start with copyright and licensing information. + Just before both, the string \texttt{\$Id\$} shall be placed as a + comment. +\item The sole language of coding and documentation is + \emph{English}. +\item A file shall end with a new line. +\end{itemize} + + +\subsection{Rules for C++} +\label{sec:rules-cpp} + +The following rules apply to all CPP sourcecode files. + +\begin{itemize} +\item The language used is C++ with STL. The target compiler is GNU + g++ 4. The author strongly promotes maintaining code compatibility + with Microsoft's Visual Studio 2008 cl compiler. +\item \emph{Avoid code duplication.} +\item All \lstinline|#endif|-statement shall be appended with a + name. For mactros encpasulation a header file, this is the filename + formatted as \lstinline|FILENAME_H_|. +\lstinline|#ifdef ... #endif| blocks shall start a new indentation +level. +\begin{lstlisting} +// do this +#ifdef DEBUG + i = 10; +#endif DEBUG + +// not this +#ifdef DEBUG + i = 10; +#endif /*DEBUG*/ + +// nor this +#ifdef DEBUG +i = 10; +#endif +\end{lstlisting} + +\item The following applies to all header file class definitions +\begin{itemize} +\item Every CPPSOM header shall be marked with \emph{\#pragma once} + AND be marked with \emph{\#ifndef/\#define/\#endif} guards. +\item CPPSOM classes used in header files shall be defined using + forward declaration. The \#include is to be done in the .cpp file. + This does not apply to the base class of the class. +\begin{lstlisting} +//do this +#include + +class VMArray; + +class MyVMObject : VMObject +{ +public: + MyVMObject(VMArray*) : VMObject(); + /* ... more public members */ +private: + VMArray* embeddedArray; +} + +//not this +#include + +#include + +class MyVMObject : VMObject +{ +public: + MyVMObject(VMArray*) : VMObject(); + /* ... more public members */ +private: + VMArray* embeddedArray; +} +\end{lstlisting} +\item There shall be exactly one space between the word class and + the class' name. +\item There shall be exactly one space before and after the colon + ':' that separates the class name from the name of the base class. +\item All class definitions should state members and methods in order + of their visibility. Start with public, then protected and finally + private. The visibility qualifiers shall be at indentation level 0. +\item Member declaration within one visibility should be done in the + order: static methods, static fields), constructors, methods, fields. +\item Methods shall only be implemented in the header if it is a + getter or setter function without further functionality besides + getting or setting the value of a member variable. +\end{itemize} +\item There shall be exactly one space between a method's type and + its name. +\begin{lstlisting} +// do this +void SomeClass::SomeMethod(String fmt, ...) +{ + ... +} + +// not this +void SomeClass::SomeMethod(String fmt, ...) +{ + ... +} +\end{lstlisting} +\item When definig methods, in a method signature, the opening + brace \lstinline|{| shall be on the next line after the corresponding + closing paren \lstinline|)| at the same indentation level as the + method's return type. +\begin{lstlisting} +// do this +void SomeClass::SomeMethod(char *fmt, ...) +{ + ... +} + +// not this +void SomeClass::SomeMethod(String fmt, ...) { + ... +} + +// nor this +void SomeClass::SomeMethod(String fmt, ...){ + ... +} + +// and not this +void SomeClass::SomeMethod(String fmt, ...) + { + ... + } +\end{lstlisting} +\item An opening paren \lstinline|(| shall not be appended, a closing + paren \lstinline|)| shall not be prepended with a space. +\begin{lstlisting} +// do this +bool right = ((a || b) && (c ^^ d)) || (e > f); + +// not this +bool right = ( ( a || b ) && ( c ^^ d ) ) || ( e > f ) ; +\end{lstlisting} +\item Functions shall not start with empty lines. Code or comments + shall start immediately. +\begin{lstlisting} +// do this +void print(char *fmt, ...) +{ + int i=0; + ... +} + +// not this +void print(char *fmt, ...) +{ + + int i=0; + ... +} +\end{lstlisting} +\item Each function definition is preceded and followed by two blank lines. +\begin{lstlisting} +// do this + + +void foo1(...) +{ + ... +} + + +void foo2(...) +{ + ... +} + + +//not this +void foo1(...) +{ + ... +} +void foo2(...) +{ + ... +} +\end{lstlisting} +\item \lstinline|**| and \lstinline|*| shall not be unnecessarily + surrounded by spaces. +\begin{lstlisting} +// do this +array = *another; + +// not this +array = * another; +\end{lstlisting} +\item When casting, the closing paren \lstinline|)| after the target type shall not + be appended by a space. +\begin{lstlisting} +// do this +foo = (char*)bar; + +// not this +foo = (char*) bar; +\end{lstlisting} +\item Redundant parens shall be avoided. +\begin{lstlisting} +// do this +return 0 == (a - b); + +// not this +return (0 == (a - b)); +\end{lstlisting} +\item In pointer definitions, the asterisk \lstinline|*| shall be + aligned to the type not to the variable's name. +\begin{lstlisting} +// do this +int* foo; + +// not this +int *foo; + +// nor this +int * foo; +\end{lstlisting} +\item Comments like \lstinline|//end of somefile.c| shall be avoided. +\item A space shall be placed behind commas \lstinline|,| in parameter + lists, base class lists et al. +\begin{lstlisting} +// do this +foo(a, b, c); + +// not this +foo(a,b,c); + +// nor this +foo(a ,b ,c); +foo(a , b , c); +\end{lstlisting} +\item Binary operators, shall be surrounded by spaces. +\begin{lstlisting} +// do this +bool right = !((++a | b) && (c ^^ d)); + +// not this +bool right=! ((++ a|b)&&(c^^d)); +\end{lstlisting} +\item \lstinline|#pragma mark| code separators are preceded and followed by two blank lines. +\begin{lstlisting} +//do this +void foo(...) +{ + ... +} + + +#pragma mark Helper functions + + +int helper(...) +{ + ... +} + +// not this +void foo(...) +{ + ... +} +#pragma mark Helper functions +int helper(...) +{ + ... +} +\end{lstlisting} +\item Backslashes \lstinline|\| shall be prepended by a space if + encountered on line endings. + \begin{lstlisting} +// do this +#define MY_LONG_MACRO_FORMAT \ + int i; \ + int j; \ + int k + +// not this +#define MY_LONG_MACRO_FORMAT\ + int i;\ + int j;\ + int k +\end{lstlisting} +\item There shall not be a space between \lstinline|if/for/while/anyFunctionName| + and the following opening paren \lstinline|(|. + \begin{lstlisting} +// do this +if(a == b) +{ + while(x > 2) + { + z = foo(x); + } +} + +// not this +if (a == b) +{ + while (x > 2) + { + z = foo (x); + } +} +\end{lstlisting} +\item \lstinline|#define| blocks shall not end with semi colon + \lstinline|;| if the macro defined will be used with semi colons + later on. This apllies especially to the \lstinline|_FORMAT| + macros. + \begin{lstlisting} +// do this +#define MY_LONG_MACRO_FORMAT \ + int i; \ + int j; \ + int k + +// not this +#define MY_LONG_MACRO_FORMAT \ + int i; \ + int j; \ + int k; +\end{lstlisting} +\item Function comments shall be written in \verb|javadoc|-style, + i.~e. at least + \begin{lstlisting} +/** + * brief description of what the function does + */ +\end{lstlisting}They are \emph{immediately} followed by the function header without any blank lines. +\item Each block of line comments shall start and end with a empty comment + line. Such blocks are also preceded and followed by two blank lines. +\begin{lstlisting} +// do this + + +// +// some useful commentary +// + + +// not this +// some less useful commentary +\end{lstlisting} +\item There are no TABs (i.~e. no ASCII character 09). The indentation + width shall be 4 spaces. +\begin{lstlisting}[showspaces] +// do this +void foo(void) +{ + int i; + if(a == ...) + { + while(true) + { + ... + } + ... + } +} +\end{lstlisting} +\lstinputlisting[showtabs]{tab.c} +\item Lines which are too long to fit the 80 columns shall be split, such + that it remains sensefully grouped. For assignation, this means to try + to keep the right side of it together. + \begin{lstlisting} +// do this +int foo = + object->SomeFunctionName(first_parameter, second_parameter, third_parameter); + +// not this +int foo = object->SomeFunctionName(first_parameter, second_parameter, + third_parameter); + \end{lstlisting} +\item When using includes from different CPPSOM-directories, they shall + be grouped and parted by empty lines. + \begin{lstlisting} +// do this +#include + +#include + +#include +#include +#include + +#include + +// not this +#include +#include +#include +#include +#include +#include +\end{lstlisting} +\end{itemize} + +\subsection{Rules fom SOM} +\label{sec:rules-fom-som} + +\subsection{Rules for Make et al.} +\label{sec:rules-make-et} + +\begin{itemize} +\item \emph{Do not use recursive makes.} +\end{itemize} + +\end{document} \ No newline at end of file diff --git a/doc/tab.c b/doc/tab.c new file mode 100644 index 0000000..fd1385c --- /dev/null +++ b/doc/tab.c @@ -0,0 +1,10 @@ +// not this +void foo(void) { + int i; + if(a==...) { + while(true) { + ... + } + ... + } +} diff --git a/src/Main.cpp b/src/Main.cpp new file mode 100644 index 0000000..9c59280 --- /dev/null +++ b/src/Main.cpp @@ -0,0 +1,54 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + +#include +#include + +#include "compiler/ClassGenerationContext.h" + +#include "memory/Heap.h" + +#include "misc/ExtendedList.h" +#include "misc/defs.h" + +#include "vm/Universe.h" + +#include "vmobjects/VMObject.h" +#include "vmobjects/VMMethod.h" +#include "vmobjects/VMString.h" +#include "vmobjects/VMArray.h" +#include "vmobjects/ObjectFormats.h" + +int main(int argc, char** argv) { + + cout << "This is SOM++.\n" << endl; + + Universe::Start(argc, argv); + + Universe::Quit(ERR_SUCCESS); +} + + diff --git a/src/compiler/BytecodeGenerator.cpp b/src/compiler/BytecodeGenerator.cpp new file mode 100644 index 0000000..1ad1680 --- /dev/null +++ b/src/compiler/BytecodeGenerator.cpp @@ -0,0 +1,144 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + +#include "BytecodeGenerator.h" + +#include "../vmobjects/VMObject.h" +#include "../vmobjects/VMMethod.h" + + +#define EMIT1(BC) \ + mgenc->AddBytecode(BC) + + +#define EMIT2(BC, IDX) \ + mgenc->AddBytecode(BC);\ + mgenc->AddBytecode(IDX) + + +#define EMIT3(BC, IDX, CTX) \ + mgenc->AddBytecode(BC);\ + mgenc->AddBytecode(IDX);\ + mgenc->AddBytecode(CTX) + + +void BytecodeGenerator::EmitHALT( MethodGenerationContext* mgenc ) { + EMIT1(BC_HALT); +} + + +void BytecodeGenerator::EmitDUP( MethodGenerationContext* mgenc ) { + EMIT1(BC_DUP); +} + + +void BytecodeGenerator::EmitPUSHLOCAL( + MethodGenerationContext* mgenc, int idx, int ctx ) { + EMIT3(BC_PUSH_LOCAL, idx, ctx); +} + + +void BytecodeGenerator::EmitPUSHARGUMENT( + MethodGenerationContext* mgenc, int idx, int ctx ) { + EMIT3(BC_PUSH_ARGUMENT, idx, ctx); +} + + +void BytecodeGenerator::EmitPUSHFIELD( + MethodGenerationContext* mgenc, pVMSymbol field ) { + EMIT2(BC_PUSH_FIELD, mgenc->FindLiteralIndex((pVMObject)field)); +} + + +void BytecodeGenerator::EmitPUSHBLOCK( + MethodGenerationContext* mgenc, pVMMethod block ) { + EMIT2(BC_PUSH_BLOCK, mgenc->FindLiteralIndex((pVMObject)(block))); +} + + +void BytecodeGenerator::EmitPUSHCONSTANT( + MethodGenerationContext* mgenc, pVMObject cst ) { + EMIT2(BC_PUSH_CONSTANT, mgenc->FindLiteralIndex(cst)); +} + + +void BytecodeGenerator::EmitPUSHCONSTANTString( + MethodGenerationContext* mgenc, pVMString str ){ + EMIT2(BC_PUSH_CONSTANT, mgenc->FindLiteralIndex((pVMObject)str)); +} + + +void BytecodeGenerator::EmitPUSHGLOBAL( + MethodGenerationContext* mgenc, pVMSymbol global ) { + EMIT2(BC_PUSH_GLOBAL, mgenc->FindLiteralIndex((pVMObject)global)); +} + + +void BytecodeGenerator::EmitPOP( MethodGenerationContext* mgenc ) { + EMIT1(BC_POP); +} + + +void BytecodeGenerator::EmitPOPLOCAL( + MethodGenerationContext* mgenc, int idx, int ctx ) { + EMIT3(BC_POP_LOCAL, idx, ctx); +} + + +void BytecodeGenerator::EmitPOPARGUMENT( + MethodGenerationContext* mgenc, int idx, int ctx ) { + EMIT3(BC_POP_ARGUMENT, idx, ctx); +} + + +void BytecodeGenerator::EmitPOPFIELD( + MethodGenerationContext* mgenc, pVMSymbol field ) { + EMIT2(BC_POP_FIELD, mgenc->FindLiteralIndex((pVMObject)field)); +} + + +void BytecodeGenerator::EmitSEND( + MethodGenerationContext* mgenc, pVMSymbol msg ) { + EMIT2(BC_SEND, mgenc->FindLiteralIndex((pVMObject)msg)); +} + + +void BytecodeGenerator::EmitSUPERSEND( + MethodGenerationContext* mgenc, pVMSymbol msg ) { + EMIT2(BC_SUPER_SEND, mgenc->FindLiteralIndex((pVMObject)msg)); +} + + +void BytecodeGenerator::EmitRETURNLOCAL( + MethodGenerationContext* mgenc ) { + EMIT1(BC_RETURN_LOCAL); +} + + +void BytecodeGenerator::EmitRETURNNONLOCAL( + MethodGenerationContext* mgenc ) { + EMIT1(BC_RETURN_NON_LOCAL); +} diff --git a/src/compiler/BytecodeGenerator.h b/src/compiler/BytecodeGenerator.h new file mode 100644 index 0000000..54ba63c --- /dev/null +++ b/src/compiler/BytecodeGenerator.h @@ -0,0 +1,65 @@ +#pragma once +#ifndef BYTECODEGENERATOR_H_ +#define BYTECODEGENERATOR_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "MethodGenerationContext.h" + +#include "../interpreter/bytecodes.h" + +#include "../misc/defs.h" + +class VMMethod; +class VMSymbol; +class VMObject; +class VMString; + +class BytecodeGenerator { +public: + void EmitHALT(MethodGenerationContext* mgenc); + void EmitDUP(MethodGenerationContext* mgenc); + void EmitPUSHLOCAL(MethodGenerationContext* mgenc, int idx, int ctx); + void EmitPUSHARGUMENT(MethodGenerationContext* mgenc, int idx, int ctx); + void EmitPUSHFIELD(MethodGenerationContext* mgenc, pVMSymbol field); + void EmitPUSHBLOCK(MethodGenerationContext* mgenc, pVMMethod block); + void EmitPUSHCONSTANT(MethodGenerationContext* mgenc, pVMObject cst); + void EmitPUSHCONSTANTString( + MethodGenerationContext* mgenc, pVMString str); + void EmitPUSHGLOBAL(MethodGenerationContext* mgenc, pVMSymbol global); + void EmitPOP(MethodGenerationContext* mgenc); + void EmitPOPLOCAL(MethodGenerationContext* mgenc, int idx, int ctx); + void EmitPOPARGUMENT(MethodGenerationContext* mgenc, int idx, int ctx); + void EmitPOPFIELD(MethodGenerationContext* mgenc, pVMSymbol field); + void EmitSEND(MethodGenerationContext* mgenc, pVMSymbol msg); + void EmitSUPERSEND(MethodGenerationContext* mgenc, pVMSymbol msg); + void EmitRETURNLOCAL(MethodGenerationContext* mgenc); + void EmitRETURNNONLOCAL(MethodGenerationContext* mgenc); +}; + +#endif diff --git a/src/compiler/ClassGenerationContext.cpp b/src/compiler/ClassGenerationContext.cpp new file mode 100644 index 0000000..406a9f1 --- /dev/null +++ b/src/compiler/ClassGenerationContext.cpp @@ -0,0 +1,120 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "ClassGenerationContext.h" + +#include "../vmobjects/VMSymbol.h" +#include "../vmobjects/VMObject.h" +#include "../vmobjects/VMClass.h" + +ClassGenerationContext::ClassGenerationContext() : + instanceFields(), instanceMethods(), classFields(), classMethods(){ + name = NULL; + superName = NULL; + classSide = false; +} + + +ClassGenerationContext::~ClassGenerationContext() { +} + + +void ClassGenerationContext::AddClassField(pVMObject field) { + this->classFields.Add(field); +} + + +void ClassGenerationContext::AddInstanceField(pVMObject field) { + this->instanceFields.Add(field); +} + + +bool ClassGenerationContext::FindField(const StdString& field) { + + ExtendedList fields = IsClassSide() ? + classFields : + instanceFields; + return fields.IndexOf( (pVMObject)_UNIVERSE->SymbolFor(field)) != -1; + +} + + + +void ClassGenerationContext::AddInstanceMethod(pVMObject method) { + this->instanceMethods.Add(method); +} + + + +void ClassGenerationContext::AddClassMethod(pVMObject method) { + this->classMethods.Add(method); +} + + +pVMClass ClassGenerationContext::Assemble() { + // build class class name + StdString ccname = string(name->GetStdString()) + " class"; + + // Load the super class + pVMClass superClass = _UNIVERSE->LoadClass(superName); + + // Allocate the class of the resulting class + pVMClass resultClass = _UNIVERSE->NewClass(metaClassClass); + + // Initialize the class of the resulting class + resultClass->SetInstanceFields(_UNIVERSE->NewArrayList(classFields)); + resultClass->SetInstanceInvokables(_UNIVERSE->NewArrayList(classMethods)); + resultClass->SetName(_UNIVERSE->SymbolFor(ccname)); + + pVMClass superMClass = superClass->GetClass(); + resultClass->SetSuperClass(superMClass); + + // Allocate the resulting class + pVMClass result = _UNIVERSE->NewClass(resultClass); + + // Initialize the resulting class + result->SetInstanceFields(_UNIVERSE->NewArrayList(instanceFields)); + result->SetInstanceInvokables(_UNIVERSE->NewArrayList(instanceMethods)); + result->SetName(this->name); + result->SetSuperClass(superClass); + + return result; +} + + + +void ClassGenerationContext::AssembleSystemClass( pVMClass systemClass ) { + systemClass->SetInstanceInvokables(_UNIVERSE->NewArrayList + (instanceMethods)); + systemClass->SetInstanceFields(_UNIVERSE->NewArrayList(instanceFields)); + // class-bound == class-instance-bound + pVMClass superMClass = systemClass->GetClass(); + superMClass->SetInstanceInvokables(_UNIVERSE->NewArrayList(classMethods)); + superMClass->SetInstanceFields(_UNIVERSE->NewArrayList(classFields)); +} + + diff --git a/src/compiler/ClassGenerationContext.h b/src/compiler/ClassGenerationContext.h new file mode 100644 index 0000000..cf9d9be --- /dev/null +++ b/src/compiler/ClassGenerationContext.h @@ -0,0 +1,73 @@ +#pragma once +#ifndef CLASSGENERATIONCONTEXT_H_ +#define CLASSGENERATIONCONTEXT_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMSymbol; +class VMObject; +class VMClass; + +#include "../vmobjects/ObjectFormats.h" +#include "../vmobjects/VMPointer.h" + +#include "../misc/defs.h" +#include "../misc/ExtendedList.h" + +class ClassGenerationContext { + +public: + ClassGenerationContext(); + ~ClassGenerationContext(); + pVMClass Assemble(); + void AssembleSystemClass(pVMClass systemClass); + + bool FindField(const StdString&); + void AddInstanceField(pVMObject); + void AddClassField(pVMObject); + void AddInstanceMethod(pVMObject); + void AddClassMethod(pVMObject); + void SetName(pVMSymbol n) { name = n; } + void SetSuperName(pVMSymbol sn) { superName = sn; } + void SetClassSide(bool cs) { classSide = cs; } + pVMSymbol GetName(void) { return name; }; + pVMSymbol GetSuperName(void) { return superName; }; + bool IsClassSide(void) { return classSide;}; + +private: + pVMSymbol name; + pVMSymbol superName; + bool classSide; + ExtendedList instanceFields; + ExtendedList instanceMethods; + ExtendedList classFields; + ExtendedList classMethods; + +}; + +#endif diff --git a/src/compiler/Disassembler.cpp b/src/compiler/Disassembler.cpp new file mode 100644 index 0000000..d4f1e90 --- /dev/null +++ b/src/compiler/Disassembler.cpp @@ -0,0 +1,456 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include + +#include "Disassembler.h" + +#include "../vm/Universe.h" + +#include "../interpreter/bytecodes.h" +#include "../interpreter/Interpreter.h" + +#include "../vmobjects/VMArray.h" +#include "../vmobjects/VMBigInteger.h" +#include "../vmobjects/VMBlock.h" +#include "../vmobjects/VMClass.h" +#include "../vmobjects/VMDouble.h" +#include "../vmobjects/VMEvaluationPrimitive.h" +#include "../vmobjects/VMFrame.h" +#include "../vmobjects/VMInteger.h" +#include "../vmobjects/VMInvokable.h" +#include "../vmobjects/VMMethod.h" +#include "../vmobjects/VMObject.h" +#include "../vmobjects/VMPrimitive.h" +#include "../vmobjects/VMString.h" +#include "../vmobjects/VMSymbol.h" +#include "../vmobjects/Signature.h" +#include "../vmobjects/VMPointerConverter.h" + +#include "../misc/debug.h" +#include "../misc/defs.h" +/** + * Dispatch an object to its content and write out + */ +void Disassembler::dispatch(pVMObject o) { + //dispatch + // can't switch() objects, so: + if(!o) return; // NULL isn't interesting. + else if(o == nilObject) + DebugPrint("{Nil}"); + else if(o == trueObject) + DebugPrint("{True}"); + else if(o == falseObject) + DebugPrint("{False}"); + else if((pVMClass)o == systemClass) + DebugPrint("{System Class object}"); + else if((pVMClass)o == blockClass) + DebugPrint("{Block Class object}"); + else if(o == _UNIVERSE->GetGlobal(_UNIVERSE->SymbolForChars("system"))) + DebugPrint("{System}"); + else { + pVMClass c = o->GetClass(); + if(c == stringClass) { + DebugPrint("\"%s\"", ((pVMString)o)->GetChars()); + } else if(c == doubleClass) + DebugPrint("%g", ((pVMDouble)o)->GetEmbeddedDouble()); + else if(c == bigIntegerClass) + DebugPrint("%lld", ((pVMBigInteger)o)->GetEmbeddedInteger()); + else if(c == integerClass) + DebugPrint("%d", ((pVMInteger)o)->GetEmbeddedInteger()); + else if(c == symbolClass) { + DebugPrint("#%s", ((pVMSymbol)o)->GetChars()); + } else + DebugPrint("address: %p", (void*)o); + } +} + +/** + * Dump a class and all subsequent methods. + */ +void Disassembler::Dump(pVMClass cl) { + for(int i = 0; i < cl->GetNumberOfInstanceInvokables(); ++i) { + pVMInvokable inv = (pVMInvokable)(cl->GetInstanceInvokable(i)); + // output header and skip if the Invokable is a Primitive + pVMSymbol sig = inv->GetSignature(); + pVMSymbol cname = cl->GetName(); + DebugDump("%s>>%s = ", cname->GetChars(), sig->GetChars()); + if(inv->IsPrimitive()) { + DebugPrint("\n"); + continue; + } + // output actual method + DumpMethod((pVMMethod)(inv), "\t"); + } +} + + +/** + * Bytecode Index Accessor macros + */ +#define BC_0 method->GetBytecode(bc_idx) +#define BC_1 method->GetBytecode(bc_idx+1) +#define BC_2 method->GetBytecode(bc_idx+2) + + +/** + * Dump all Bytecode of a method. + */ +void Disassembler::DumpMethod(pVMMethod method, const char* indent) { + DebugPrint("(\n"); + { // output stack information + int locals = method->GetNumberOfLocals(); + int max_stack = method->GetMaximumNumberOfStackElements(); + DebugDump("%s<%d locals, %d stack, %d bc_count>\n", indent, locals, + max_stack, method->GetNumberOfBytecodes()); + } +#ifdef _DEBUG + cout << "bytecodes: "; + for (int i = 0; i < method->GetNumberOfBytecodes(); ++i) { + cout << (int)(*method)[i] << " "; + } + cout << endl; +#endif + // output bytecodes + for(int bc_idx = 0; + bc_idx < method->GetNumberOfBytecodes(); + bc_idx += Bytecode::GetBytecodeLength(method->GetBytecode(bc_idx)) ) { + // the bytecode. + uint8_t bytecode = BC_0; + // indent, bytecode index, bytecode mnemonic + DebugDump("%s%4d:%s ", indent, bc_idx, + Bytecode::GetBytecodeName(bytecode)); + // parameters (if any) + if(Bytecode::GetBytecodeLength(bytecode) == 1) { + DebugPrint("\n"); + continue; + } + switch(bytecode) { + case BC_PUSH_LOCAL: + DebugPrint("local: %d, context: %d\n", BC_1, BC_2); break; + case BC_PUSH_ARGUMENT: + DebugPrint("argument: %d, context %d\n", BC_1, BC_2); break; + case BC_PUSH_FIELD:{ + pVMObject cst = method->GetConstant(bc_idx); + + if (cst != NULL) { + pVMSymbol name = DynamicConvert(cst); + if (name != NULL) { + DebugPrint("(index: %d) field: %s\n", BC_1, + name->GetChars()); + break; + } + } else + DebugPrint("(index: %d) field: !NULL!: error!\n", BC_1); + break; + } + case BC_PUSH_BLOCK: { + char* nindent = new char[strlen(indent)+1+1]; + DebugPrint("block: (index: %d) ", BC_1); + sprintf(nindent, "%s\t", indent); + + Disassembler::DumpMethod( + (pVMMethod)(method->GetConstant(bc_idx)), nindent); + break; + } + case BC_PUSH_CONSTANT: { + pVMObject constant = method->GetConstant(bc_idx); + pVMClass cl = constant->GetClass(); + pVMSymbol cname = cl->GetName(); + + DebugPrint("(index: %d) value: (%s) ", + BC_1, cname->GetChars()); + dispatch(constant); DebugPrint("\n"); + break; + } + case BC_PUSH_GLOBAL: { + pVMObject cst = method->GetConstant(bc_idx); + + if (cst != NULL) { + pVMSymbol name = DynamicConvert(cst); + if (name != NULL) { + DebugPrint("(index: %d) value: %s\n", BC_1, + name->GetChars()); + break; + } + } else + DebugPrint("(index: %d) value: !NULL!: error!\n", BC_1); + + break; + } + case BC_POP_LOCAL: + DebugPrint("local: %d, context: %d\n", BC_1, BC_2); + break; + case BC_POP_ARGUMENT: + DebugPrint("argument: %d, context: %d\n", BC_1, BC_2); + break; + case BC_POP_FIELD: { + pVMSymbol name = (pVMSymbol)(method->GetConstant(bc_idx)); + + DebugPrint("(index: %d) field: %s\n", BC_1, name->GetChars()); + break; + } + case BC_SEND: { + pVMSymbol name = (pVMSymbol)(method->GetConstant(bc_idx)); + + DebugPrint("(index: %d) signature: %s\n", BC_1, + name->GetChars()); + break; + } + case BC_SUPER_SEND: { + pVMSymbol name = (pVMSymbol)(method->GetConstant(bc_idx)); + + DebugPrint("(index: %d) signature: %s\n", BC_1, + name->GetChars()); + break; + } + default: + DebugPrint("\n"); + } + } + DebugDump("%s)\n", indent); +} + +/** + * Dump bytecode from the frame running + */ +void Disassembler::DumpBytecode(pVMFrame frame, pVMMethod method, int bc_idx) { + static long long indentc = 0; + static char ikind = '@'; + uint8_t bc = BC_0; + pVMObject clo = method->GetHolder(); + pVMClass cl = DynamicConvert(clo); + // Determine Context: Class or Block? + if(cl != NULL) { + pVMSymbol cname = cl->GetName(); + pVMSymbol sig = method->GetSignature(); + + DebugTrace("%20s>>%-20s% 10lld %c %04d: %s\t", + cname->GetChars(), sig->GetChars(), + indentc, ikind, bc_idx, + Bytecode::GetBytecodeName(bc)); + } else { + pVMSymbol sig = method->GetSignature(); + + DebugTrace("%-42s% 10lld %c %04d: %s\t", + sig->GetChars(), + indentc, ikind, bc_idx, + Bytecode::GetBytecodeName(bc)); + } + // reset send indicator + if(ikind != '@') ikind = '@'; + + switch(bc) { + case BC_HALT: { + DebugPrint("\n\n\n"); + break; + } + case BC_DUP: { + pVMObject o = frame->GetStackElement(0); + if(o) { + pVMClass c = o->GetClass(); + pVMSymbol cname = c->GetName(); + + DebugPrint("GetChars()); + //dispatch + dispatch(o); + } else + DebugPrint("\n"); + break; + } + case BC_PUSH_LOCAL: { + uint8_t bc1 = BC_1, bc2 = BC_2; + pVMObject o = frame->GetLocal(bc1, bc2); + pVMClass c = o->GetClass(); + pVMSymbol cname = c->GetName(); + + DebugPrint("local: %d, context: %d <(%s) ", + BC_1, BC_2, cname->GetChars()); + //dispatch + dispatch(o); + DebugPrint(">\n"); + break; + } + case BC_PUSH_ARGUMENT: { + uint8_t bc1 = BC_1, bc2 = BC_2; + pVMObject o = frame->GetArgument(bc1, bc2); + DebugPrint("argument: %d, context: %d", bc1, bc2); + if(DynamicConvert(cl) != NULL) { + pVMClass c = o->GetClass(); + pVMSymbol cname = c->GetName(); + + DebugPrint("<(%s) ", cname->GetChars()); + //dispatch + dispatch(o); + DebugPrint(">"); + } + DebugPrint("\n"); + break; + } + case BC_PUSH_FIELD: { + pVMFrame ctxt = frame->GetOuterContext(); + pVMObject arg = ctxt->GetArgument(0, 0); + pVMSymbol name = (pVMSymbol)(method->GetConstant(bc_idx)); + int field_index = arg->GetFieldIndex(name); + + pVMObject o = arg->GetField(field_index); + pVMClass c = o->GetClass(); + pVMSymbol cname = c->GetName(); + + DebugPrint("(index: %d) field: %s <(%s) ", BC_1, + name->GetChars(), cname->GetChars()); + //dispatch + dispatch(o); + DebugPrint(">\n"); + break; + } + case BC_PUSH_BLOCK: { + DebugPrint("block: (index: %d) ", BC_1); + pVMMethod meth = (pVMMethod)(method->GetConstant(bc_idx)); + DumpMethod(meth, "$"); + break; + } + case BC_PUSH_CONSTANT: { + pVMObject constant = method->GetConstant(bc_idx); + pVMClass c = constant->GetClass(); + pVMSymbol cname = c->GetName(); + + DebugPrint("(index: %d) value: (%s) ", BC_1, + cname->GetChars()); + dispatch(constant); + DebugPrint("\n"); + break; + } + case BC_PUSH_GLOBAL: { + pVMSymbol name = (pVMSymbol)(method->GetConstant(bc_idx)); + pVMObject o = _UNIVERSE->GetGlobal(name); + pVMSymbol cname; + + char* c_cname; + if(o) { + pVMClass c = o->GetClass(); + cname = c->GetName(); + + c_cname = cname->GetChars(); + } else + c_cname = "NULL"; + + DebugPrint("(index: %d)value: %s <(%s) ", BC_1, + name->GetChars(), c_cname); + dispatch(o); + DebugPrint(">\n"); + break; + } + case BC_POP: { + size_t sp = frame->GetStackPointer()->GetEmbeddedInteger(); + pVMObject o = (*(pVMArray)frame)[sp]; + pVMClass c = o->GetClass(); + pVMSymbol cname = c->GetName(); + + DebugPrint("popped <(%s) ", cname->GetChars()); + //dispatch + dispatch(o); + DebugPrint(">\n"); + break; + } + case BC_POP_LOCAL: { + size_t sp = frame->GetStackPointer()->GetEmbeddedInteger(); + pVMObject o = (*(pVMArray)frame)[sp]; + pVMClass c = o->GetClass(); + pVMSymbol cname = c->GetName(); + + DebugPrint("popped local: %d, context: %d <(%s) ", BC_1, BC_2, + cname->GetChars()); + //dispatch + dispatch(o); + DebugPrint(">\n"); + break; + } + case BC_POP_ARGUMENT: { + size_t sp = frame->GetStackPointer()->GetEmbeddedInteger(); + pVMObject o = (*(pVMArray)frame)[sp]; + pVMClass c = o->GetClass(); + pVMSymbol cname = c->GetName(); + DebugPrint("argument: %d, context: %d <(%s) ", BC_1, BC_2, + cname->GetChars()); + //dispatch + dispatch(o); + DebugPrint(">\n"); + break; + } + case BC_POP_FIELD: { + size_t sp = frame->GetStackPointer()->GetEmbeddedInteger(); + pVMObject o = (*(pVMArray)frame)[sp]; + pVMSymbol name = (pVMSymbol)(method->GetConstant(bc_idx)); + pVMClass c = o->GetClass(); + pVMSymbol cname = c->GetName(); + + DebugPrint("(index: %d) field: %s <(%s) ", BC_1, + name->GetChars(), + cname->GetChars()); + dispatch(o); + DebugPrint(">\n"); + break; + } + case BC_SUPER_SEND: + case BC_SEND: { + pVMSymbol sel = (pVMSymbol)(method->GetConstant(bc_idx)); + + DebugPrint("(index: %d) signature: %s (", BC_1, + sel->GetChars()); + //handle primitives, they don't increase call-depth + pVMObject elem = _UNIVERSE->GetInterpreter()->GetFrame()-> + GetStackElement( + Signature::GetNumberOfArguments(sel)-1); + pVMClass elemClass = elem->GetClass(); + pVMInvokable inv = DynamicConvert( + elemClass->LookupInvokable(sel)); + + if(inv != NULL && inv->IsPrimitive()) + DebugPrint("*)\n"); + else { + DebugPrint("\n"); + indentc++; ikind='>'; // visual + } + break; + } + case BC_RETURN_LOCAL: + case BC_RETURN_NON_LOCAL: { + DebugPrint(")\n"); + indentc--; ikind='<'; //visual + break; + } + default: + DebugPrint("\n"); + break; + } +} + +// EOF: diassembler.c + diff --git a/src/compiler/Disassembler.h b/src/compiler/Disassembler.h new file mode 100644 index 0000000..4ad9dc0 --- /dev/null +++ b/src/compiler/Disassembler.h @@ -0,0 +1,46 @@ +#pragma once +#ifndef DISASSEMBELR_H_ +#define DISASSEMBELR_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "../vmobjects/VMClass.h" +#include "../vmobjects/VMMethod.h" +#include "../vmobjects/VMFrame.h" + +class Disassembler { +public: + static void Dump(pVMClass cl); + static void DumpMethod(pVMMethod method, const char* indent); + static void DumpBytecode(pVMFrame frame, pVMMethod method, int bc_idx); +private: + static void dispatch(pVMObject o); +}; + +#endif + diff --git a/src/compiler/Lexer.cpp b/src/compiler/Lexer.cpp new file mode 100644 index 0000000..4a3bc9f --- /dev/null +++ b/src/compiler/Lexer.cpp @@ -0,0 +1,250 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include + +#include "Lexer.h" + + +Lexer::Lexer(istream &file) : infile(file) { + peekDone = false; + bufp = 0; + lineNumber = 0; +} + +Lexer::~Lexer() { +} + + +StdString Lexer::GetText(void) { + return StdString(text); +} + +StdString Lexer::GetNextText(void) { + return StdString(nextText); +} + +StdString Lexer::GetRawBuffer(void) { + //for debug + return StdString(buf); +} + +#define _BC (buf[bufp]) +#define EOB (bufp >= buf.length()) + +int Lexer::fillBuffer(void) { + if(!infile.good()) // file stream + return 0; + + std::getline(infile, buf); + ++lineNumber; + bufp = 0; + return buf.length(); +} + + +// +// basic lexing +// + +void Lexer::skipWhiteSpace(void) { + while(isspace(_BC)) { + bufp++; + if(EOB) + fillBuffer(); + } +} + + +void Lexer::skipComment(void) { + + if(_BC == '"') { + do { + bufp++; + if(EOB) + fillBuffer(); + } while(_BC != '"'); + bufp++; + } +} + + +#define _ISOP(C) \ + ((C) == '~' || (C) == '&' || (C) == '|' || (C) == '*' || (C) == '/' || \ + (C) == '\\' || (C) == '+' || (C) == '=' || (C) == '>' || (C) == '<' || \ + (C) == ',' || (C) == '@' || (C) == '%') +#define _MATCH(C, S) \ + if(_BC == (C)) { sym = (S); symc = _BC; sprintf(text, "%c", _BC); bufp++;} +#define SEPARATOR StdString("----") //FIXME +#define PRIMITIVE StdString("primitive") + +Symbol Lexer::GetSym(void) { + if(peekDone) { + peekDone = false; + sym = nextSym; + symc = nextSymc; + strncpy(text, nextText, 512); + return sym; + } + + do { + if(EOB) + fillBuffer(); + skipWhiteSpace(); + skipComment(); + + } while((EOB || isspace(_BC) || _BC == '"') && infile.good()); + + if(_BC == '\'') { + sym = STString; + symc = 0; + char* t = text; + do { + *t++ = buf[++bufp]; + + } while(_BC != '\''); + + bufp++; + *--t = 0; + } + else _MATCH('[', NewBlock) + else _MATCH(']', EndBlock) + else if(_BC == ':') { + if(buf[bufp+1] == '=') { + bufp += 2; + sym = Assign; + symc = 0; + sprintf(text, ":="); + } else { + bufp++; + sym = Colon; + symc = ':'; + sprintf(text, ":"); + } + } + else _MATCH('(', NewTerm) + else _MATCH(')', EndTerm) + else _MATCH('#', Pound) + else _MATCH('^', Exit) + else _MATCH('.', Period) + else if(_BC == '-') { + if(!buf.substr(bufp, SEPARATOR.length()).compare(SEPARATOR)) { + char* t = text; + while(_BC == '-') + *t++ = buf[bufp++]; + *t = 0; + sym = Separator; + } else { + bufp++; + sym = Minus; + symc = '-'; + sprintf(text, "-"); + } + } + else if(_ISOP(_BC)) { + if(_ISOP(buf[bufp + 1])) { + sym = OperatorSequence; + symc = 0; + char* t = text; + while(_ISOP(_BC)) + *t++ = buf[bufp++]; + *t = 0; + } + else _MATCH('~', Not) + else _MATCH('&', And) + else _MATCH('|', Or) + else _MATCH('*', Star) + else _MATCH('/', Div) + else _MATCH('\\', Mod) + else _MATCH('+', Plus) + else _MATCH('=', Equal) + else _MATCH('>', More) + else _MATCH('<', Less) + else _MATCH(',', Comma) + else _MATCH('@', At) + else _MATCH('%', Per) + } + else if (!buf.substr(bufp, PRIMITIVE.length()).compare(PRIMITIVE)) { + bufp += PRIMITIVE.length(); + sym = Primitive; + symc = 0; + sprintf(text, "primitive"); + } + else if(isalpha(_BC)) { + char* t = text; + symc = 0; + while(isalpha(_BC) || isdigit(_BC) || _BC == '_') + *t++ = buf[bufp++]; + sym = Identifier; + if(buf[bufp] == ':') { + sym = Keyword; + bufp++; + *t++ = ':'; + if(isalpha(_BC)) { + sym = KeywordSequence; + while(isalpha(_BC) || _BC == ':') + *t++ = buf[bufp++]; + } + } + *t = 0; + } + else if(isdigit(_BC)) { + sym = Integer; + symc = 0; + char* t = text; + do { + *t++ = buf[bufp++]; + } while(isdigit(_BC)); + *t = 0; + } + else { + sym = NONE; + symc = _BC; + sprintf(text, "%c", _BC); + } + + return sym; +} + + +Symbol Lexer::Peek(void) { + Symbol saveSym = sym; + char saveSymc = symc; + char saveText[256]; + strcpy(saveText, text); + if(peekDone) + fprintf(stderr, "Cannot Peek twice!\n"); + GetSym(); + nextSym = sym; + nextSymc = symc; + strcpy(nextText, text); + sym = saveSym; + symc = saveSymc; + strcpy(text, saveText); + peekDone = true; + return nextSym; +} diff --git a/src/compiler/Lexer.h b/src/compiler/Lexer.h new file mode 100644 index 0000000..2f23da2 --- /dev/null +++ b/src/compiler/Lexer.h @@ -0,0 +1,95 @@ +#pragma once +#ifndef LEXER_H_ +#define LEXER_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include + +#include "../misc/defs.h" + +using namespace std; + +typedef enum { + NONE, Integer, Not, And, Or, Star, Div, Mod, Plus, + Minus, Equal, More, Less, Comma, At, Per, NewBlock, + EndBlock, Colon, Period, Exit, Assign, NewTerm, EndTerm, Pound, + Primitive, Separator, STString, Identifier, Keyword, KeywordSequence, + OperatorSequence +} Symbol; +static const char* symnames[] = { + "NONE", "Integer", "Not", "And", "Or", "Star", "Div", "Mod", "Plus", + "Minus", "Equal", "More", "Less", "Comma", "At", "Per", "NewBlock", + "EndBlock", "Colon", "Period", "Exit", "Assign", "NewTerm", "EndTerm", + "Pound", "Primitive", "Separator", "STString", "Identifier", "Keyword", + "KeywordSequence", "OperatorSequence" +}; + +class Lexer { + +public: + Lexer(istream& file); + Lexer(const StdString& stream); + ~Lexer(); + Symbol GetSym(void); + Symbol Peek(void); + StdString GetText(void); + StdString GetNextText(void); + StdString GetRawBuffer(void); + int GetCurrentLineNumber() { return lineNumber; }; + +private: + int fillBuffer(void); + void skipWhiteSpace(void); + void skipComment(void); + + Lexer &operator=(const Lexer& /*src*/) { + } + + istream& infile; + + StdString stringInput; + + Symbol sym; + char symc; + + char text[BUFSIZ]; + + int lineNumber; + bool peekDone; + Symbol nextSym; + char nextSymc; + //^^ + char nextText[BUFSIZ]; + + StdString buf; + unsigned int bufp; +}; + +#endif diff --git a/src/compiler/MethodGenerationContext.cpp b/src/compiler/MethodGenerationContext.cpp new file mode 100644 index 0000000..538176e --- /dev/null +++ b/src/compiler/MethodGenerationContext.cpp @@ -0,0 +1,239 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + +#include "MethodGenerationContext.h" + +#include "../interpreter/bytecodes.h" + +#include "../vmobjects/VMSymbol.h" +#include "../vmobjects/VMMethod.h" +#include "../vmobjects/Signature.h" +#include "../vmobjects/VMMethod.h" +#include "../vmobjects/VMPrimitive.h" + +MethodGenerationContext::MethodGenerationContext() { + //signature = 0; + holderGenc = 0; + outerGenc = 0; + this->arguments.Clear(); + this->literals.Clear(); + this->locals.Clear(); + this->bytecode.clear(); + primitive = false; + blockMethod = false; + finished = false; +} + +pVMMethod MethodGenerationContext::Assemble() { + // create a method instance with the given number of bytecodes and literals + int numLiterals = this->literals.Size(); + + pVMMethod meth = _UNIVERSE->NewMethod(this->signature, bytecode.size(), + numLiterals); + + // populate the fields that are immediately available + int numLocals = this->locals.Size(); + meth->SetNumberOfLocals(numLocals); + + meth->SetMaximumNumberOfStackElements(this->ComputeStackDepth()); + + // copy literals into the method + for(int i = 0; i < numLiterals; i++) { + pVMObject l = literals.Get(i); + meth->SetIndexableField(i, l); + } + // copy bytecodes into method + for(size_t i = 0; i < bytecode.size(); i++){ + meth->SetBytecode(i, bytecode[i]); + } + // return the method - the holder field is to be set later on! + return meth; +} + +pVMPrimitive MethodGenerationContext::AssemblePrimitive() { + return VMPrimitive::GetEmptyPrimitive(this->signature); +} + +MethodGenerationContext::~MethodGenerationContext() { +} + +int8_t MethodGenerationContext::FindLiteralIndex(pVMObject lit) { + return (int8_t)literals.IndexOf(lit); + +} + +bool MethodGenerationContext::FindVar(const StdString& var, int* index, + int* context, bool* isArgument) { + if((*index = locals.IndexOf( var)) == -1) { + if((*index = arguments.IndexOf( var)) == -1) { + if(!outerGenc) + return false; + else { + (*context)++; + return outerGenc->FindVar(var, index, + context, isArgument); + } + } else + *isArgument = true; + } + + return true; +} + +bool MethodGenerationContext::FindField(const StdString& field) { + return holderGenc->FindField(field); +} + +int MethodGenerationContext::GetNumberOfArguments() { + return arguments.Size(); +} + +uint8_t MethodGenerationContext::ComputeStackDepth() { + uint8_t depth = 0; + uint8_t maxDepth = 0; + unsigned int i = 0; + + while(i < bytecode.size()) { + switch(bytecode[i]) { + case BC_HALT : i++; break; + case BC_DUP : depth++; i++; break; + case BC_PUSH_LOCAL : + case BC_PUSH_ARGUMENT : depth++; i += 3; break; + case BC_PUSH_FIELD : + case BC_PUSH_BLOCK : + case BC_PUSH_CONSTANT : + case BC_PUSH_GLOBAL : depth++; i += 2; break; + case BC_POP : depth--; i++; break; + case BC_POP_LOCAL : + case BC_POP_ARGUMENT : depth--; i += 3; break; + case BC_POP_FIELD : depth--; i += 2; break; + case BC_SEND : + case BC_SUPER_SEND : { + // these are special: they need to look at the number of + // arguments (extractable from the signature) + pVMSymbol sig = (pVMSymbol)literals.Get(bytecode[i + 1]); + + depth -= Signature::GetNumberOfArguments(sig); + + depth++; // return value + i += 2; + break; + } + case BC_RETURN_LOCAL : + case BC_RETURN_NON_LOCAL : i++; break; + default : + cout << "Illegal bytecode: " << bytecode[i]; + _UNIVERSE->Quit(1); + } + + if(depth > maxDepth) + maxDepth = depth; + } + + return maxDepth; +} + + +void MethodGenerationContext::SetHolder(ClassGenerationContext* holder) { + holderGenc = holder; +} + +void MethodGenerationContext::SetOuter(MethodGenerationContext* outer) { + outerGenc = outer; +} + +void MethodGenerationContext::SetIsBlockMethod(bool isBlock) { + blockMethod = isBlock; +} + +void MethodGenerationContext::SetSignature(pVMSymbol sig) { + signature = sig; +} + +void MethodGenerationContext::SetPrimitive(bool prim) { + primitive = prim; +} + +void MethodGenerationContext::AddArgument(const StdString& arg) { + arguments.PushBack(arg); +} + +void MethodGenerationContext::AddLocal(const StdString& local) { + locals.PushBack(local); +} + +void MethodGenerationContext::AddLiteral(pVMObject lit) { + literals.PushBack(lit); +} + +bool MethodGenerationContext::AddArgumentIfAbsent(const StdString& arg) { + if (locals.IndexOf( arg) != -1) return false; + arguments.PushBack(arg); + return true; +} + +bool MethodGenerationContext::AddLocalIfAbsent(const StdString& local) { + if (locals.IndexOf( local) != -1) return false; + locals.PushBack(local); + return true; +} + +bool MethodGenerationContext::AddLiteralIfAbsent(pVMObject lit) { + if (literals.IndexOf( lit) != -1) return false; + literals.PushBack(lit); + return true; +} +void MethodGenerationContext::SetFinished(bool finished) { + this->finished = finished; +} + +ClassGenerationContext* MethodGenerationContext::GetHolder() { + return holderGenc; +} + +MethodGenerationContext* MethodGenerationContext::GetOuter() { + return outerGenc; +} + +pVMSymbol MethodGenerationContext::GetSignature() { + return signature; +} + +bool MethodGenerationContext::IsPrimitive() { + return primitive; +} + +bool MethodGenerationContext::IsBlockMethod() { + return blockMethod; +} + +bool MethodGenerationContext::IsFinished() { + return finished; +} + +void MethodGenerationContext::AddBytecode(uint8_t bc) { + bytecode.push_back(bc); +} diff --git a/src/compiler/MethodGenerationContext.h b/src/compiler/MethodGenerationContext.h new file mode 100644 index 0000000..406d3f3 --- /dev/null +++ b/src/compiler/MethodGenerationContext.h @@ -0,0 +1,93 @@ +#pragma once +#ifndef METHODGENERATIONCONTEXT_H_ +#define METHODGENERATIONCONTEXT_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include + +#include "../misc/defs.h" +#include "../misc/ExtendedList.h" + +#include "ClassGenerationContext.h" + +class VMMethod; +class VMArray; +class VMPrimitive; + +class MethodGenerationContext { +public: + MethodGenerationContext(); + ~MethodGenerationContext(); + + pVMMethod Assemble(); + pVMPrimitive AssemblePrimitive(); + + int8_t FindLiteralIndex(pVMObject lit); + bool FindVar(const StdString& var, int* index, + int* context, bool* isArgument); + bool FindField(const StdString& field); + uint8_t ComputeStackDepth(); + + void SetHolder(ClassGenerationContext* holder); + void SetOuter(MethodGenerationContext* outer); + void SetIsBlockMethod(bool isBlock = true); + void SetSignature(pVMSymbol sig); + void AddArgument(const StdString& arg); + void SetPrimitive(bool prim = true); + void AddLocal(const StdString& local); + void AddLiteral(pVMObject lit); + bool AddArgumentIfAbsent(const StdString& arg); + bool AddLocalIfAbsent(const StdString& local); + bool AddLiteralIfAbsent(pVMObject lit); + void SetFinished(bool finished = true); + + ClassGenerationContext* GetHolder(); + MethodGenerationContext* GetOuter(); + + pVMSymbol GetSignature(); + bool IsPrimitive(); + bool IsBlockMethod(); + bool IsFinished(); + void RemoveLastBytecode() { bytecode.pop_back(); }; + int GetNumberOfArguments(); + void AddBytecode(uint8_t bc); +private: + ClassGenerationContext* holderGenc; + MethodGenerationContext* outerGenc; + bool blockMethod; + pVMSymbol signature; + ExtendedList arguments; + bool primitive; + ExtendedList locals; + ExtendedList literals; + bool finished; + std::vector bytecode; +}; + +#endif diff --git a/src/compiler/Parser.cpp b/src/compiler/Parser.cpp new file mode 100644 index 0000000..6ce998e --- /dev/null +++ b/src/compiler/Parser.cpp @@ -0,0 +1,785 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "Parser.h" +#include "BytecodeGenerator.h" + +#include "../vmobjects/VMMethod.h" +#include "../vmobjects/VMPrimitive.h" +#include "../vmobjects/VMObject.h" +#include "../vmobjects/VMSymbol.h" + +#include "../vm/Universe.h" + +#include +#include +#include +#include +#include + + +#define GETSYM sym = lexer->GetSym(); \ + text = lexer->GetText() + +#define PEEK nextSym = lexer->Peek(); \ + nextText = lexer->GetNextText() + +Parser::Parser(istream& file) { + sym = NONE; + lexer = new Lexer(file); + bcGen = new BytecodeGenerator(); + nextSym = NONE; + + GETSYM; +} + +Parser::~Parser() { + delete(lexer); + delete(bcGen); +} + +// +// parsing +// + + +bool Parser::symIn(Symbol* ss) { + while(*ss) + if(*ss++ == sym) + return true; + return false; +} + + +bool Parser::accept(Symbol s) { + if(sym == s) { + GETSYM; + return true; + } + return false; +} + + +bool Parser::acceptOneOf(Symbol* ss) { + if(symIn(ss)) { + GETSYM; + return true; + } + return false; +} + + +#define _PRINTABLE_SYM (sym == Integer || sym >= STString) + + +bool Parser::expect(Symbol s) { + if(accept(s)) + return true; + fprintf(stderr, "Error: unexpected symbol in line %d. Expected %s, but found %s", + lexer->GetCurrentLineNumber(), symnames[s], symnames[sym]); + if(_PRINTABLE_SYM) + fprintf(stderr, " (%s)", text.c_str()); + fprintf(stderr, ": %s\n", lexer->GetRawBuffer().c_str()); + return false; +} + + +bool Parser::expectOneOf(Symbol* ss) { + if(acceptOneOf(ss)) + return true; + fprintf(stderr, "Error: unexpected symbol in line %d. Expected one of ", + lexer->GetCurrentLineNumber()); + while(*ss) + fprintf(stderr, "%s, ", symnames[*ss++]); + fprintf(stderr, "but found %s", symnames[sym]); + if(_PRINTABLE_SYM) + fprintf(stderr, " (%s)", text.c_str()); + fprintf(stderr, ": %s\n", lexer->GetRawBuffer().c_str()); + return false; +} + + + + +void Parser::genPushVariable(MethodGenerationContext* mgenc, const StdString& var) { + // The purpose of this function is to find out whether the variable to be + // pushed on the stack is a local variable, argument, or object field. This + // is done by examining all available lexical contexts, starting with the + // innermost (i.e., the one represented by mgenc). + int index = 0; + int context = 0; + bool is_argument = false; + + if(mgenc->FindVar(var, &index, &context, &is_argument)) { + if(is_argument) + bcGen->EmitPUSHARGUMENT(mgenc, index, context); + else + bcGen->EmitPUSHLOCAL(mgenc, index, context); + } else if(mgenc->FindField(var)) { + pVMSymbol fieldName = _UNIVERSE->SymbolFor(var); + mgenc->AddLiteralIfAbsent((pVMObject)fieldName); + bcGen->EmitPUSHFIELD(mgenc, fieldName); + } else { + + pVMSymbol global = _UNIVERSE->SymbolFor(var); + mgenc->AddLiteralIfAbsent((pVMObject)global); + + bcGen->EmitPUSHGLOBAL(mgenc, global); + } +} + + +void Parser::genPopVariable(MethodGenerationContext* mgenc, const StdString& var){ + // The purpose of this function is to find out whether the variable to be + // popped off the stack is a local variable, argument, or object field. This + // is done by examining all available lexical contexts, starting with the + // innermost (i.e., the one represented by mgenc). + int index = 0; + int context = 0; + bool is_argument = false; + + if(mgenc->FindVar(var, &index, &context, &is_argument)) { + if(is_argument) bcGen->EmitPOPARGUMENT(mgenc, index, context); + else bcGen->EmitPOPLOCAL(mgenc, index, context); + } else bcGen->EmitPOPFIELD(mgenc, _UNIVERSE->SymbolFor(var)); +} + + +// +// grammar +// + + +Symbol singleOpSyms[] = { + Not, And, Or, Star, Div, Mod, Plus, Equal, More, Less, Comma, At, Per, NONE +}; + + +Symbol binaryOpSyms[] = { + Or, Comma, Minus, Equal, Not, And, Or, Star, Div, Mod, Plus, Equal, + More, Less, Comma, At, Per, NONE +}; + + +Symbol keywordSelectorSyms[] = { Keyword, KeywordSequence }; + + + + +void Parser::Classdef(ClassGenerationContext* cgenc) { + cgenc->SetName(_UNIVERSE->SymbolFor(text)); + expect(Identifier); + + expect(Equal); + + if(sym == Identifier) { + cgenc->SetSuperName(_UNIVERSE->SymbolFor(text)); + accept(Identifier); + } else cgenc->SetSuperName(_UNIVERSE->SymbolFor("Object")); + + expect(NewTerm); + instanceFields(cgenc); + while(sym == Identifier || sym == Keyword || sym == OperatorSequence || + symIn(binaryOpSyms)) { + + MethodGenerationContext* mgenc = new MethodGenerationContext(); + mgenc->SetHolder(cgenc); + mgenc->AddArgument("self"); + + method(mgenc); + + if(mgenc->IsPrimitive()) + cgenc->AddInstanceMethod((pVMObject)(mgenc->AssemblePrimitive())); + else + cgenc->AddInstanceMethod((pVMObject)(mgenc->Assemble())); + delete(mgenc); + } + + if(accept(Separator)) { + cgenc->SetClassSide(true); + classFields(cgenc); + while(sym == Identifier || sym == Keyword || sym == OperatorSequence || + symIn(binaryOpSyms)) { + MethodGenerationContext* mgenc = new MethodGenerationContext(); + mgenc->SetHolder(cgenc); + mgenc->AddArgument("self"); + + method(mgenc); + + if(mgenc->IsPrimitive()) + cgenc->AddClassMethod((pVMObject)mgenc->AssemblePrimitive()); + else + cgenc->AddClassMethod((pVMObject)mgenc->Assemble()); + delete(mgenc); + } + } + expect(EndTerm); +} + + +void Parser::instanceFields(ClassGenerationContext* cgenc) { + if(accept(Or)) { + while(sym == Identifier) { + StdString var = variable(); + cgenc->AddInstanceField((pVMObject)_UNIVERSE->SymbolFor(var)); + } + expect(Or); + } +} + + +void Parser::classFields(ClassGenerationContext* cgenc) { + if(accept(Or)) { + while(sym == Identifier) { + StdString var = variable(); + cgenc->AddClassField((pVMObject)_UNIVERSE->SymbolFor(var)); + } + expect(Or); + } +} + + +void Parser::method(MethodGenerationContext* mgenc) { + pattern(mgenc); + + expect(Equal); + if(sym == Primitive) { + mgenc->SetPrimitive(true); + primitiveBlock(); + } else + methodBlock(mgenc); +} + + +void Parser::primitiveBlock(void) { + expect(Primitive); +} + + +void Parser::pattern(MethodGenerationContext* mgenc) { + switch(sym) { + case Identifier: + unaryPattern(mgenc); + break; + case Keyword: + keywordPattern(mgenc); + break; + default: + binaryPattern(mgenc); + break; + } +} + + +void Parser::unaryPattern(MethodGenerationContext* mgenc) { + mgenc->SetSignature(unarySelector()); +} + + +void Parser::binaryPattern(MethodGenerationContext* mgenc) { + mgenc->SetSignature(binarySelector()); + mgenc->AddArgumentIfAbsent(argument()); +} + + +void Parser::keywordPattern(MethodGenerationContext* mgenc) { + StdString kw; + do { + kw.append(keyword()); + mgenc->AddArgumentIfAbsent(argument()); + } while(sym == Keyword); + + mgenc->SetSignature(_UNIVERSE->SymbolFor(kw)); +} + + +void Parser::methodBlock(MethodGenerationContext* mgenc){ + expect(NewTerm); + blockContents(mgenc); + // if no return has been generated so far, we can be sure there was no . + // terminating the last expression, so the last expression's value must be + // popped off the stack and a ^self be generated + if(!mgenc->IsFinished()) { + bcGen->EmitPOP(mgenc); + bcGen->EmitPUSHARGUMENT(mgenc, 0, 0); + bcGen->EmitRETURNLOCAL(mgenc); + mgenc->SetFinished(); + } + + expect(EndTerm); +} + + +pVMSymbol Parser::unarySelector(void) { + return _UNIVERSE->SymbolFor(identifier()); +} + + +pVMSymbol Parser::binarySelector(void) { + StdString s(text); + + if(accept(Or)) + ; + else if(accept(Comma)) + ; + else if(accept(Minus)) + ; + else if(accept(Equal)) + ; + else if(acceptOneOf(singleOpSyms)) + ; + else if(accept(OperatorSequence)) + ; + else + expect(NONE); + + pVMSymbol symb = _UNIVERSE->SymbolFor(s); + return symb; +} + + +StdString Parser::identifier(void) { + StdString s(text); + if(accept(Primitive)) + ; // text is set + else + expect(Identifier); + + return s; +} + + +StdString Parser::keyword(void) { + StdString s(text); + expect(Keyword); + + return s; +} + + +StdString Parser::argument(void) { + return variable(); +} + + +void Parser::blockContents(MethodGenerationContext* mgenc) { + if(accept(Or)) { + locals(mgenc); + expect(Or); + } + blockBody(mgenc, false); +} + + +void Parser::locals(MethodGenerationContext* mgenc) +{ + while(sym == Identifier) + mgenc->AddLocalIfAbsent(variable()); +} + + +void Parser::blockBody(MethodGenerationContext* mgenc, bool seen_period) { + if(accept(Exit)) + result(mgenc); + else if(sym == EndBlock) { + if(seen_period) { + // a POP has been generated which must be elided (blocks always + // return the value of the last expression, regardless of whether it + // was terminated with a . or not) + mgenc->RemoveLastBytecode(); + } + bcGen->EmitRETURNLOCAL(mgenc); + + mgenc->SetFinished(); + } else if(sym == EndTerm) { + if(seen_period) + // we can be sure it's a method we're parsing, not a block, so the + // PUSH_ARGUMENT can be created immediately + bcGen->EmitPUSHARGUMENT(mgenc, 0, 0); + bcGen->EmitRETURNLOCAL(mgenc); + mgenc->SetFinished(); + } else { + expression(mgenc); + if(accept(Period)) { + bcGen->EmitPOP(mgenc); + blockBody(mgenc, true); + } + } +} + + +void Parser::result(MethodGenerationContext* mgenc) { + expression(mgenc); + + if(mgenc->IsBlockMethod()) bcGen->EmitRETURNNONLOCAL(mgenc); + else bcGen->EmitRETURNLOCAL(mgenc); + + mgenc->SetFinished(true); + accept(Period); +} + + +void Parser::expression(MethodGenerationContext* mgenc) { + PEEK; + if(nextSym == Assign) + assignation(mgenc); + else + evaluation(mgenc); +} + + +void Parser::assignation(MethodGenerationContext* mgenc) { + list l; + + assignments(mgenc, l); + evaluation(mgenc); + list::iterator i; + for(i=l.begin(); i != l.end(); ++i) + bcGen->EmitDUP(mgenc); + for(i=l.begin(); i != l.end(); ++i) + genPopVariable(mgenc, (*i)); + +} + + +void Parser::assignments(MethodGenerationContext* mgenc, list& l) { + if(sym == Identifier) { + l.push_back(assignment(mgenc)); + PEEK; + if(nextSym == Assign) + assignments(mgenc, l); + } +} + + +StdString Parser::assignment(MethodGenerationContext* mgenc) { + StdString v = variable(); + pVMSymbol var = _UNIVERSE->SymbolFor(v); + mgenc->AddLiteralIfAbsent((pVMObject)var); + + expect(Assign); + + return v; +} + + +void Parser::evaluation(MethodGenerationContext* mgenc) { + bool super; + primary(mgenc, &super); + if(sym == Identifier || sym == Keyword || sym == OperatorSequence || + symIn(binaryOpSyms)) { + messages(mgenc, super); + } +} + + +void Parser::primary(MethodGenerationContext* mgenc, bool* super) { + *super = false; + switch(sym) { + case Identifier: { + StdString v = variable(); + if(v == "super") { + *super = true; + // sends to super push self as the receiver + v = StdString("self"); + } + + genPushVariable(mgenc, v); + break; + } + case NewTerm: + nestedTerm(mgenc); + break; + case NewBlock: { + MethodGenerationContext* bgenc = new MethodGenerationContext(); + bgenc->SetIsBlockMethod(true); + bgenc->SetHolder(mgenc->GetHolder()); + bgenc->SetOuter(mgenc); + + nestedBlock(bgenc); + + pVMMethod block_method = bgenc->Assemble(); + mgenc->AddLiteral(block_method); + bcGen->EmitPUSHBLOCK(mgenc, block_method); + delete(bgenc); + break; + } + default: + literal(mgenc); + break; + } +} + + +StdString Parser::variable(void) { + return identifier(); +} + + +void Parser::messages(MethodGenerationContext* mgenc, bool super) { + if(sym == Identifier) { + do { + // only the first message in a sequence can be a super send + unaryMessage(mgenc, super); + super = false; + } while(sym == Identifier); + + while(sym == OperatorSequence || symIn(binaryOpSyms)) { + binaryMessage(mgenc, false); + } + + if(sym == Keyword) { + keywordMessage(mgenc, false); + } + } else if(sym == OperatorSequence || symIn(binaryOpSyms)) { + do { + // only the first message in a sequence can be a super send + binaryMessage(mgenc, super); + super = false; + } while(sym == OperatorSequence || symIn(binaryOpSyms)); + + if(sym == Keyword) { + keywordMessage(mgenc, false); + } + } else + keywordMessage(mgenc, super); +} + + +void Parser::unaryMessage(MethodGenerationContext* mgenc, bool super) { + pVMSymbol msg = unarySelector(); + mgenc->AddLiteralIfAbsent((pVMObject)msg); + + if(super) bcGen->EmitSUPERSEND(mgenc, msg); + else bcGen->EmitSEND(mgenc, msg); + +} + + +void Parser::binaryMessage(MethodGenerationContext* mgenc, bool super) { + pVMSymbol msg = binarySelector(); + mgenc->AddLiteralIfAbsent((pVMObject)msg); + + + bool tmp_bool = false; + binaryOperand(mgenc, &tmp_bool); + + if(super) + bcGen->EmitSUPERSEND(mgenc, msg); + else + bcGen->EmitSEND(mgenc, msg); + +} + + +void Parser::binaryOperand(MethodGenerationContext* mgenc, bool* super) { + primary(mgenc, super); + + while(sym == Identifier) + unaryMessage(mgenc, *super); +} + + +void Parser::keywordMessage(MethodGenerationContext* mgenc, bool super) { + StdString kw; + do { + kw.append(keyword()); + formula(mgenc); + } while(sym == Keyword); + + pVMSymbol msg = _UNIVERSE->SymbolFor(kw); + + mgenc->AddLiteralIfAbsent((pVMObject)msg); + + + if(super) bcGen->EmitSUPERSEND(mgenc, msg); + else bcGen->EmitSEND(mgenc, msg); + +} + + +void Parser::formula(MethodGenerationContext* mgenc) { + bool super; + binaryOperand(mgenc, &super); + + // only the first message in a sequence can be a super send + if(sym == OperatorSequence || symIn(binaryOpSyms)) + binaryMessage(mgenc, super); + while(sym == OperatorSequence || symIn(binaryOpSyms)) + binaryMessage(mgenc, false); +} + + +void Parser::nestedTerm(MethodGenerationContext* mgenc) { + expect(NewTerm); + expression(mgenc); + expect(EndTerm); +} + + +void Parser::literal(MethodGenerationContext* mgenc) { + switch(sym) { + case Pound: + literalSymbol(mgenc); + break; + case STString: + literalString(mgenc); + break; + default: + literalNumber(mgenc); + break; + } +} + + +void Parser::literalNumber(MethodGenerationContext* mgenc) { + int32_t val; + if(sym == Minus) + val = negativeDecimal(); + else + val = literalDecimal(); + + pVMInteger lit = _UNIVERSE->NewInteger(val); + mgenc->AddLiteralIfAbsent((pVMObject)lit); + bcGen->EmitPUSHCONSTANT(mgenc, (pVMObject)lit); +} + + +uint32_t Parser::literalDecimal(void) { + return literalInteger(); +} + + +int32_t Parser::negativeDecimal(void) { + expect(Minus); + return -((int32_t)literalInteger()); +} + + +uint32_t Parser::literalInteger(void) { + uint32_t i = (uint32_t) strtoul(text.c_str(), NULL, 10); + expect(Integer); + return i; +} + + +void Parser::literalSymbol(MethodGenerationContext* mgenc) { + pVMSymbol symb; + expect(Pound); + if(sym == STString) { + StdString s = _string(); + symb = _UNIVERSE->SymbolFor(s); + + } else + symb = selector(); + mgenc->AddLiteralIfAbsent((pVMObject)symb); + + bcGen->EmitPUSHCONSTANT(mgenc, (pVMObject)symb); +} + + +void Parser::literalString(MethodGenerationContext* mgenc) { + StdString s = _string(); + + pVMString str = _UNIVERSE->NewString(s); + mgenc->AddLiteralIfAbsent((pVMObject)str); + + bcGen->EmitPUSHCONSTANT(mgenc,(pVMObject)str); + +} + + +pVMSymbol Parser::selector(void) { + if(sym == OperatorSequence || symIn(singleOpSyms)) + return binarySelector(); + else if(sym == Keyword || sym == KeywordSequence) + return keywordSelector(); + else + return unarySelector(); +} + + +pVMSymbol Parser::keywordSelector(void) { + StdString s(text); + expectOneOf(keywordSelectorSyms); + pVMSymbol symb = _UNIVERSE->SymbolFor(s); + return symb; +} + + +StdString Parser::_string(void) { + StdString s(text); + expect(STString); + return s; // <-- Literal strings are At Most BUFSIZ chars long. +} + + +void Parser::nestedBlock(MethodGenerationContext* mgenc) { + #define BLOCK_METHOD_S "$block method" + #define BLOCK_METHOD_LEN (13) + mgenc->AddArgumentIfAbsent("$block self"); + + expect(NewBlock); + if(sym == Colon) + blockPattern(mgenc); + + // generate Block signature + StdString block_sig = StdString(BLOCK_METHOD_S); + size_t arg_size = mgenc->GetNumberOfArguments(); + for(size_t i = 1; i < arg_size; i++) + block_sig += ":"; + + mgenc->SetSignature(_UNIVERSE->SymbolFor(block_sig)); + + blockContents(mgenc); + + // if no return has been generated, we can be sure that the last expression + // in the block was not terminated by ., and can generate a return + if(!mgenc->IsFinished()) { + bcGen->EmitRETURNLOCAL(mgenc); + mgenc->SetFinished(true); + } + + expect(EndBlock); +} + + +void Parser::blockPattern(MethodGenerationContext* mgenc) { + blockArguments(mgenc); + expect(Or); +} + + +void Parser::blockArguments(MethodGenerationContext* mgenc) { + do { + expect(Colon); + mgenc->AddArgumentIfAbsent(argument()); + + } while(sym == Colon); +} + + diff --git a/src/compiler/Parser.h b/src/compiler/Parser.h new file mode 100644 index 0000000..a13bf01 --- /dev/null +++ b/src/compiler/Parser.h @@ -0,0 +1,119 @@ +#pragma once +#ifndef PARSER_H_ +#define PARSER_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include + +#include "../misc/defs.h" + +#include "Lexer.h" +#include "ClassGenerationContext.h" +#include "MethodGenerationContext.h" +#include "BytecodeGenerator.h" + + +class Parser { +public: + Parser(istream& file); + ~Parser(); + + void Classdef(ClassGenerationContext* cgenc); +private: + bool eob(void); + + bool symIn(Symbol* ss); + bool accept(Symbol s); + bool acceptOneOf(Symbol* ss); + bool expect(Symbol s); + bool expectOneOf(Symbol* ss); + void SingleOperator(void); + void instanceFields(ClassGenerationContext* cgenc); + void classFields(ClassGenerationContext* cgenc); + void method(MethodGenerationContext* mgenc); + void primitiveBlock(void); + void pattern(MethodGenerationContext* mgenc); + void unaryPattern(MethodGenerationContext* mgenc); + void binaryPattern(MethodGenerationContext* mgenc); + void keywordPattern(MethodGenerationContext* mgenc); + void methodBlock(MethodGenerationContext* mgenc); + pVMSymbol unarySelector(void); + pVMSymbol binarySelector(void); + StdString identifier(void); + StdString keyword(void); + StdString argument(void); + void blockContents(MethodGenerationContext* mgenc); + void locals(MethodGenerationContext* mgenc); + void blockBody(MethodGenerationContext* mgenc, bool seen_period); + void result(MethodGenerationContext* mgenc); + void expression(MethodGenerationContext* mgenc); + void assignation(MethodGenerationContext* mgenc); + void assignments(MethodGenerationContext* mgenc, list& l); + StdString assignment(MethodGenerationContext* mgenc); + void evaluation(MethodGenerationContext* mgenc); + void primary(MethodGenerationContext* mgenc, bool* super); + StdString variable(void); + void messages(MethodGenerationContext* mgenc, bool super); + void unaryMessage(MethodGenerationContext* mgenc, bool super); + void binaryMessage(MethodGenerationContext* mgenc, bool super); + void binaryOperand(MethodGenerationContext* mgenc, bool* super); + void keywordMessage(MethodGenerationContext* mgenc, bool super); + void formula(MethodGenerationContext* mgenc); + void nestedTerm(MethodGenerationContext* mgenc); + void literal(MethodGenerationContext* mgenc); + void literalNumber(MethodGenerationContext* mgenc); + uint32_t literalDecimal(void); + int32_t negativeDecimal(void); + uint32_t literalInteger(void); + void literalSymbol(MethodGenerationContext* mgenc); + void literalString(MethodGenerationContext* mgenc); + pVMSymbol selector(void); + pVMSymbol keywordSelector(void); + StdString _string(void); + void nestedBlock(MethodGenerationContext* mgenc); + void blockPattern(MethodGenerationContext* mgenc); + void blockArguments(MethodGenerationContext* mgenc); + void genPushVariable(MethodGenerationContext*, const StdString&); + void genPopVariable(MethodGenerationContext*, const StdString&); + + Lexer* lexer; + + Symbol sym; + + StdString text; + + Symbol nextSym; + + StdString nextText; + + BytecodeGenerator* bcGen; +}; + +#endif diff --git a/src/compiler/SourcecodeCompiler.cpp b/src/compiler/SourcecodeCompiler.cpp new file mode 100644 index 0000000..3676681 --- /dev/null +++ b/src/compiler/SourcecodeCompiler.cpp @@ -0,0 +1,130 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include + +#include "SourcecodeCompiler.h" +#include "ClassGenerationContext.h" +#include "Parser.h" + +#include "../vmobjects/VMClass.h" +#include "../vmobjects/VMSymbol.h" + +//#define COMPILER_DEBUG + + +SourcecodeCompiler::SourcecodeCompiler() { + parser = NULL; +} + + +SourcecodeCompiler::~SourcecodeCompiler() { + if (parser != NULL) delete(parser); +} + + +pVMClass SourcecodeCompiler::CompileClass( const StdString& path, + const StdString& file, + pVMClass systemClass ) { + pVMClass result = systemClass; + + StdString fname = path + fileSeparator + file + ".som"; + + ifstream* fp = new ifstream(); + fp->open(fname.c_str(), std::ios_base::in); + if (!fp->is_open()) { + return NULL; + } + + if (parser != NULL) delete(parser); + parser = new Parser(*fp); + result = compile(systemClass); + + pVMSymbol cname = result->GetName(); + StdString cnameC = cname->GetStdString(); + + if (file != cnameC) { + + ostringstream Str; + Str << "Filename: " << file << " does not match class name " << cnameC; + + showCompilationError(file, Str.str().c_str()); + return NULL; + } + delete(parser); + parser = NULL; + delete(fp); +#ifdef COMPILER_DEBUG + std::cout << "Compilation finished" << endl; +#endif + return result; +} + + +pVMClass SourcecodeCompiler::CompileClassString( const StdString& stream, + pVMClass systemClass ) { + istringstream* ss = new istringstream(stream); + if (parser != NULL) delete(parser); + parser = new Parser(*ss); + + pVMClass result = compile(systemClass); + delete(parser); + parser = NULL; + delete(ss); + + return result; +} + + +void SourcecodeCompiler::showCompilationError( const StdString& filename, + const char* message ) { + cout << "Error when compiling " << filename << ":" << endl; + cout << message << endl; +} + + +pVMClass SourcecodeCompiler::compile( pVMClass systemClass ) { + if (parser == NULL) { + cout << "Parser not initiated" << endl; + _UNIVERSE->ErrorExit("Compiler error"); + } + ClassGenerationContext* cgc = new ClassGenerationContext(); + + pVMClass result = systemClass; + + parser->Classdef(cgc); + + if (systemClass == NULL) result = cgc->Assemble(); + else cgc->AssembleSystemClass(result); + + delete(cgc); + + + return result; +} + diff --git a/src/compiler/SourcecodeCompiler.h b/src/compiler/SourcecodeCompiler.h new file mode 100644 index 0000000..8c92de4 --- /dev/null +++ b/src/compiler/SourcecodeCompiler.h @@ -0,0 +1,55 @@ +#pragma once +#ifndef SOURCECODECOMPILER_H_ +#define SOURCECODECOMPILER_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "../misc/defs.h" + +#include "../vmobjects/ObjectFormats.h" +#include "../vmobjects/VMPointer.h" + +class VMClass; +class Parser; + +class SourcecodeCompiler +{ +public: + SourcecodeCompiler(); + ~SourcecodeCompiler(); + + pVMClass CompileClass(const StdString& path, const StdString& file, + pVMClass systemClass); + pVMClass CompileClassString(const StdString& stream, pVMClass systemClass); +private: + void showCompilationError(const StdString& filename, const char* message); + pVMClass compile(pVMClass systemClass); + Parser* parser; +}; + +#endif diff --git a/src/cppsom_dll.vcproj b/src/cppsom_dll.vcproj new file mode 100644 index 0000000..5ab4b29 --- /dev/null +++ b/src/cppsom_dll.vcproj @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/interpreter/Interpreter.cpp b/src/interpreter/Interpreter.cpp new file mode 100644 index 0000000..55ee62d --- /dev/null +++ b/src/interpreter/Interpreter.cpp @@ -0,0 +1,398 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "Interpreter.h" +#include "bytecodes.h" + +#include "../vmobjects/VMMethod.h" +#include "../vmobjects/VMFrame.h" +#include "../vmobjects/VMMethod.h" +#include "../vmobjects/VMClass.h" +#include "../vmobjects/VMObject.h" +#include "../vmobjects/VMSymbol.h" +#include "../vmobjects/VMInvokable.h" +#include "../vmobjects/Signature.h" +#include "../vmobjects/VMPointerConverter.h" + +#include "../compiler/Disassembler.h" + + +// convenience macros for frequently used function invocations +#define _FRAME this->GetFrame() +#define _SETFRAME(f) this->SetFrame(f) +#define _METHOD this->GetMethod() +#define _SELF this->GetSelf() + + +Interpreter::Interpreter() { + this->frame = NULL; + + uG = "unknownGlobal:"; + dnu = "doesNotUnderstand:arguments:"; + eB = "escapedBlock:"; + +} + + +Interpreter::~Interpreter() { + +} + + +void Interpreter::Start() { + while (true) { + int bytecodeIndex = _FRAME->GetBytecodeIndex(); + + pVMMethod method = this->GetMethod(); + uint8_t bytecode = method->GetBytecode(bytecodeIndex); + + int bytecodeLength = Bytecode::GetBytecodeLength(bytecode); + + if(dumpBytecodes >1) + Disassembler::DumpBytecode(_FRAME, method, bytecodeIndex); + + int nextBytecodeIndex = bytecodeIndex + bytecodeLength; + + _FRAME->SetBytecodeIndex(nextBytecodeIndex); + +// Handle the current bytecode + switch(bytecode) { + case BC_HALT: return; // handle the halt bytecode + case BC_DUP: doDup(); break; + case BC_PUSH_LOCAL: doPushLocal(bytecodeIndex); break; + case BC_PUSH_ARGUMENT: doPushArgument(bytecodeIndex); break; + case BC_PUSH_FIELD: doPushField(bytecodeIndex); break; + case BC_PUSH_BLOCK: doPushBlock(bytecodeIndex); break; + case BC_PUSH_CONSTANT: doPushConstant(bytecodeIndex); break; + case BC_PUSH_GLOBAL: doPushGlobal(bytecodeIndex); break; + case BC_POP: doPop(); break; + case BC_POP_LOCAL: doPopLocal(bytecodeIndex); break; + case BC_POP_ARGUMENT: doPopArgument(bytecodeIndex); break; + case BC_POP_FIELD: doPopField(bytecodeIndex); break; + case BC_SEND: doSend(bytecodeIndex); break; + case BC_SUPER_SEND: doSuperSend(bytecodeIndex); break; + case BC_RETURN_LOCAL: doReturnLocal(); break; + case BC_RETURN_NON_LOCAL: doReturnNonLocal(); break; + default: _UNIVERSE->ErrorExit( + "Interpreter: Unexpected bytecode"); + } // switch + } // while +} + + +pVMFrame Interpreter::PushNewFrame( pVMMethod method ) { + _SETFRAME(_UNIVERSE->NewFrame(_FRAME, method)); + return _FRAME; +} + + +void Interpreter::SetFrame( pVMFrame frame ) { + this->frame = frame; +} + + +pVMFrame Interpreter::GetFrame() { + return this->frame; +} + + +pVMMethod Interpreter::GetMethod() { + pVMMethod method = _FRAME->GetMethod(); + /* cout << "bytecodes: "; + for (int i = 0; i < method->BytecodeLength(); ++i) + { + cout << (int)(*method)[i] << " "; + } + cout << endl;*/ + return method; +} + + +pVMObject Interpreter::GetSelf() { + pVMFrame context = _FRAME->GetOuterContext(); + return context->GetArgument(0,0); +} + + +pVMFrame Interpreter::popFrame() { + pVMFrame result = _FRAME; + this->SetFrame(_FRAME->GetPreviousFrame()); + + result->ClearPreviousFrame(); + + return result; +} + + +void Interpreter::popFrameAndPushResult( pVMObject result ) { + pVMFrame prevFrame = this->popFrame(); + + pVMMethod method = prevFrame->GetMethod(); + int numberOfArgs = method->GetNumberOfArguments(); + + for (int i = 0; i < numberOfArgs; ++i) _FRAME->Pop(); + + _FRAME->Push(result); +} + + +void Interpreter::send( pVMSymbol signature, pVMClass receiverClass) { + pVMInvokable invokable = + DynamicConvert( receiverClass->LookupInvokable(signature) ); + + if (invokable != NULL) { + (*invokable)(_FRAME); + } else { + //doesNotUnderstand + int numberOfArgs = Signature::GetNumberOfArguments(signature); + + pVMObject receiver = _FRAME->GetStackElement(numberOfArgs-1); + + pVMArray argumentsArray = _UNIVERSE->NewArray(numberOfArgs); + + for (int i = numberOfArgs - 1; i >= 0; --i) { + pVMObject o = _FRAME->Pop(); + (*argumentsArray)[i] = o; + } + pVMObject arguments[] = { (pVMObject)signature, + (pVMObject)argumentsArray }; + + //check if current frame is big enough for this unplanned Send + //doesNotUnderstand: needs 3 slots, one for this, one for method name, one for args + int additionalStackSlots = 3 - _FRAME->RemainingStackSize(); + if (additionalStackSlots > 0) { + //copy current frame into a bigger one and replace the current frame + this->SetFrame(VMFrame::EmergencyFrameFrom(_FRAME, additionalStackSlots)); + } + + receiver->Send(dnu, arguments, 2); + } +} + + +void Interpreter::doDup() { + pVMObject elem = _FRAME->GetStackElement(0); + _FRAME->Push(elem); +} + + +void Interpreter::doPushLocal( int bytecodeIndex ) { + pVMMethod method = _METHOD; + uint8_t bc1 = method->GetBytecode(bytecodeIndex + 1); + uint8_t bc2 = method->GetBytecode(bytecodeIndex + 2); + + pVMObject local = _FRAME->GetLocal(bc1, bc2); + + _FRAME->Push(local); +} + + +void Interpreter::doPushArgument( int bytecodeIndex ) { + pVMMethod method = _METHOD; + uint8_t bc1 = method->GetBytecode(bytecodeIndex + 1); + uint8_t bc2 = method->GetBytecode(bytecodeIndex + 2); + + pVMObject argument = _FRAME->GetArgument(bc1, bc2); + + _FRAME->Push(argument); +} + + +void Interpreter::doPushField( int bytecodeIndex ) { + pVMMethod method = _METHOD; + + pVMSymbol fieldName = (pVMSymbol) method->GetConstant(bytecodeIndex); + + pVMObject self = _SELF; + int fieldIndex = self->GetFieldIndex(fieldName); + + pVMObject o = self->GetField(fieldIndex); + + _FRAME->Push(o); +} + + +void Interpreter::doPushBlock( int bytecodeIndex ) { + pVMMethod method = _METHOD; + + pVMMethod blockMethod = (pVMMethod)(method->GetConstant(bytecodeIndex)); + + int numOfArgs = blockMethod->GetNumberOfArguments(); + + _FRAME->Push((pVMObject) _UNIVERSE->NewBlock(blockMethod, _FRAME, + numOfArgs)); +} + + +void Interpreter::doPushConstant( int bytecodeIndex ) { + pVMMethod method = _METHOD; + + pVMObject constant = method->GetConstant(bytecodeIndex); + _FRAME->Push(constant); +} + + +void Interpreter::doPushGlobal( int bytecodeIndex) { + + + pVMMethod method = _METHOD; + + pVMSymbol globalName = (pVMSymbol) method->GetConstant(bytecodeIndex); + + pVMObject global = _UNIVERSE->GetGlobal(globalName); + + if(global != NULL) + _FRAME->Push(global); + else { + pVMObject arguments[] = { (pVMObject) globalName }; + pVMObject self = _SELF; + + //check if there is enough space on the stack for this unplanned Send + //unknowGlobal: needs 2 slots, one for "this" and one for the argument + int additionalStackSlots = 2 - _FRAME->RemainingStackSize(); + if (additionalStackSlots > 0) { + //copy current frame into a bigger one and replace the current frame + this->SetFrame(VMFrame::EmergencyFrameFrom(_FRAME, + additionalStackSlots)); + } + + self->Send(uG, arguments, 1); + } +} + + +void Interpreter::doPop() { + _FRAME->Pop(); +} + + +void Interpreter::doPopLocal( int bytecodeIndex ) { + pVMMethod method = _METHOD; + uint8_t bc1 = method->GetBytecode(bytecodeIndex + 1); + uint8_t bc2 = method->GetBytecode(bytecodeIndex + 2); + + pVMObject o = _FRAME->Pop(); + + _FRAME->SetLocal(bc1, bc2, o); +} + + +void Interpreter::doPopArgument( int bytecodeIndex ) { + pVMMethod method = _METHOD; + + uint8_t bc1 = method->GetBytecode(bytecodeIndex + 1); + uint8_t bc2 = method->GetBytecode(bytecodeIndex + 2); + + pVMObject o = _FRAME->Pop(); + _FRAME->SetArgument(bc1, bc2, o); +} + + +void Interpreter::doPopField( int bytecodeIndex ) { + pVMMethod method = _METHOD; + pVMSymbol field_name = (pVMSymbol) method->GetConstant(bytecodeIndex); + + pVMObject self = _SELF; + int field_index = self->GetFieldIndex(field_name); + + pVMObject o = _FRAME->Pop(); + self->SetField(field_index, o); +} + + +void Interpreter::doSend( int bytecodeIndex ) { + pVMMethod method = _METHOD; + + pVMSymbol signature = (pVMSymbol) method->GetConstant(bytecodeIndex); + + int numOfArgs = Signature::GetNumberOfArguments(signature); + + pVMObject receiver = _FRAME->GetStackElement(numOfArgs-1); + + this->send(signature, receiver->GetClass()); +} + + +void Interpreter::doSuperSend( int bytecodeIndex ) { + pVMMethod method = _METHOD; + pVMSymbol signature = (pVMSymbol) method->GetConstant(bytecodeIndex); + + pVMFrame ctxt = _FRAME->GetOuterContext(); + pVMMethod realMethod = ctxt->GetMethod(); + pVMClass holder = realMethod->GetHolder(); + pVMClass super = holder->GetSuperClass(); + pVMInvokable invokable = DynamicConvert( + super->LookupInvokable(signature) ); + + if (invokable != NULL) + (*invokable)(_FRAME); + else { + int numOfArgs = Signature::GetNumberOfArguments(signature); + pVMObject receiver = _FRAME->GetStackElement(numOfArgs - 1); + pVMArray argumentsArray = _UNIVERSE->NewArray(numOfArgs); + + for (int i = numOfArgs - 1; i >= 0; --i) { + pVMObject o = _FRAME->Pop(); + (*argumentsArray)[i] = o; + } + pVMObject arguments[] = { (pVMObject)signature, + (pVMObject) argumentsArray }; + receiver->Send(dnu, arguments, 2); + } +} + + +void Interpreter::doReturnLocal() { + pVMObject result = _FRAME->Pop(); + + this->popFrameAndPushResult(result); +} + + +void Interpreter::doReturnNonLocal() { + pVMObject result = _FRAME->Pop(); + + pVMFrame context = _FRAME->GetOuterContext(); + + if (!context->HasPreviousFrame()) { + pVMBlock block = (pVMBlock) _FRAME->GetArgument(0, 0); + pVMFrame prevFrame = _FRAME->GetPreviousFrame(); + pVMFrame outerContext = prevFrame->GetOuterContext(); + pVMObject sender = outerContext->GetArgument(0, 0); + pVMObject arguments[] = { (pVMObject)block }; + + this->popFrame(); + + sender->Send(eB, arguments, 1); + return; + } + + while (_FRAME != context) this->popFrame(); + + this->popFrameAndPushResult(result); +} + diff --git a/src/interpreter/Interpreter.h b/src/interpreter/Interpreter.h new file mode 100644 index 0000000..7085e02 --- /dev/null +++ b/src/interpreter/Interpreter.h @@ -0,0 +1,81 @@ +#pragma once +#ifndef INTERPRETER_H_ +#define INTERPRETER_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "../misc/defs.h" + +#include "../vmobjects/ObjectFormats.h" +#include "../vmobjects/VMPointer.h" + +class VMMethod; +class VMFrame; +class VMMethod; +class VMObject; +class VMSymbol; +class VMClass; + +class Interpreter { +public: + Interpreter(); + ~Interpreter(); + void Start(); + pVMFrame PushNewFrame(pVMMethod method); + void SetFrame(pVMFrame frame); + pVMFrame GetFrame(); + pVMMethod GetMethod(); + pVMObject GetSelf(); +private: + pVMFrame frame; + StdString uG; + StdString dnu; + StdString eB; + + pVMFrame popFrame(); + void popFrameAndPushResult(pVMObject result); + void send(pVMSymbol signature, pVMClass receiverClass); + + void doDup(); + void doPushLocal(int bytecodeIndex); + void doPushArgument(int bytecodeIndex); + void doPushField(int bytecodeIndex); + void doPushBlock(int bytecodeIndex); + void doPushConstant(int bytecodeIndex); + void doPushGlobal(int bytecodeIndex); + void doPop(void); + void doPopLocal(int bytecodeIndex); + void doPopArgument(int bytecodeIndex); + void doPopField(int bytecodeIndex); + void doSend(int bytecodeIndex); + void doSuperSend(int bytecodeIndex); + void doReturnLocal(); + void doReturnNonLocal(); +}; + +#endif diff --git a/src/interpreter/bytecodes.cpp b/src/interpreter/bytecodes.cpp new file mode 100644 index 0000000..a355d91 --- /dev/null +++ b/src/interpreter/bytecodes.cpp @@ -0,0 +1,68 @@ +#include "bytecodes.h" + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +const uint8_t Bytecode::bytecodeLengths[] = { + 1, // BC_HALT + 1, // BC_DUP + 3, // BC_PUSH_LOCAL + 3, // BC_PUSH_ARGUMENT + 2, // BC_PUSH_FIELD + 2, // BC_PUSH_BLOCK + 2, // BC_PUSH_CONSTANT + 2, // BC_PUSH_GLOBAL + 1, // BC_POP + 3, // BC_POP_LOCAL + 3, // BC_POP_ARGUMENT + 2, // BC_POP_FIELD + 2, // BC_SEND + 2, // BC_SUPER_SEND + 1, // BC_RETURN_LOCAL + 1 // BC_RETURN_NON_LOCAL +}; + +const char* Bytecode::bytecodeNames[] = { + "HALT ", + "DUP ", + "PUSH_LOCAL ", + "PUSH_ARGUMENT ", + "PUSH_FIELD ", + "PUSH_BLOCK ", + "PUSH_CONSTANT ", + "PUSH_GLOBAL ", + "POP ", + "POP_LOCAL ", + "POP_ARGUMENT ", + "POP_FIELD ", + "SEND ", + "SUPER_SEND ", + "RETURN_LOCAL ", + "RETURN_NON_LOCAL" +}; + + diff --git a/src/interpreter/bytecodes.h b/src/interpreter/bytecodes.h new file mode 100644 index 0000000..3ffcfce --- /dev/null +++ b/src/interpreter/bytecodes.h @@ -0,0 +1,77 @@ +#pragma once +#ifndef BYTECODES_H_ +#define BYTECODES_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "../misc/defs.h" + +// bytecode constants used by SOM++ + +#define BC_HALT 0 +#define BC_DUP 1 +#define BC_PUSH_LOCAL 2 +#define BC_PUSH_ARGUMENT 3 +#define BC_PUSH_FIELD 4 +#define BC_PUSH_BLOCK 5 +#define BC_PUSH_CONSTANT 6 +#define BC_PUSH_GLOBAL 7 +#define BC_POP 8 +#define BC_POP_LOCAL 9 +#define BC_POP_ARGUMENT 10 +#define BC_POP_FIELD 11 +#define BC_SEND 12 +#define BC_SUPER_SEND 13 +#define BC_RETURN_LOCAL 14 +#define BC_RETURN_NON_LOCAL 15 + +// bytecode lengths + + +class Bytecode { + +public: + static char* GetBytecodeName(uint8_t bc) { + return (char*)bytecodeNames[bc]; + } + + static uint8_t GetBytecodeLength(uint8_t bc) { + + return bytecodeLengths[bc];// Return the length of the given bytecode + } + +private: + +static const uint8_t bytecodeLengths[]; + +static const char* bytecodeNames[]; +}; + + + +#endif diff --git a/src/memory/GarbageCollector.cpp b/src/memory/GarbageCollector.cpp new file mode 100644 index 0000000..4d1257f --- /dev/null +++ b/src/memory/GarbageCollector.cpp @@ -0,0 +1,194 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include +#include + +#include "GarbageCollector.h" +#include "Heap.h" + +#include "../vm/Universe.h" + +#include "../vmobjects/VMMethod.h" +#include "../vmobjects/VMObject.h" +#include "../vmobjects/VMFreeObject.h" +#include "../vmobjects/VMSymbol.h" +#include "../vmobjects/VMPointer.h" + +GarbageCollector::GarbageCollector(Heap* h) { + heap = h; + numCollections = 0; + numLive = 0; + spcLive = 0; + numFreed = 0; + spcFreed = 0; + +} + + +GarbageCollector::~GarbageCollector() { + //Heap is deleted by Universe +} + + +void GarbageCollector::Collect() { + ++numCollections; + numLive = 0; + spcLive = 0; + numFreed = 0; + spcFreed = 0; + markReachableObjects(); + void* pointer = heap->objectSpace; + VMFreeObject* lastUnusedObject = NULL; + long bytesToSkip = 0; + + //reset freeList, will be rebuilt during sweeping + heap->freeListStart = NULL; + + //start sweeping + //iterate through the whole heap + do { //end of heap not reached yet? + //everything in the heap is an vmobject + VMObject* curObject = (VMObject*) pointer; + if (curObject->GetGCField() != -1) { + //current object is not marked as being unused + if (curObject->GetGCField() == 1) { + //found alive object + + ++numLive; + spcLive += curObject->GetObjectSize(); + curObject->SetGCField(0); + } else { + //found trash + ++numFreed; + int freedBytes = curObject->GetObjectSize(); + spcFreed += freedBytes; + memset(curObject, 0, freedBytes); + + //mark object as unused + curObject->SetGCField(-1); + curObject->SetObjectSize(freedBytes); + VMFreeObject* curFree = (VMFreeObject*) curObject; + if (heap->freeListStart == NULL) { + heap->freeListStart = curFree; + } else { + lastUnusedObject->SetNext(curFree); + } + curFree->SetPrevious(lastUnusedObject); + lastUnusedObject = curFree; + + } + } else { + VMFreeObject* curFree = (VMFreeObject*)curObject; + //store the unused object for merging purposes + if (heap->freeListStart == NULL) + heap->freeListStart = curFree; + else + lastUnusedObject->SetNext(curFree); + curFree->SetPrevious(lastUnusedObject); + lastUnusedObject = curFree; + } + pointer = (void*)((long)pointer + curObject->GetObjectSize()); + }while((long)pointer < ((long)(void*)heap->objectSpace) + heap->objectSpaceSize); + + mergeFreeSpaces(); + + if(gcVerbosity > 1) + this->PrintCollectStat(); + if(gcVerbosity > 2) { + cerr << "TODO: dump heap" << endl; + } +} + + +void GarbageCollector::markReachableObjects() { + map globals = Universe::GetUniverse()->GetGlobals(); + for (map::iterator it = globals.begin(); + it!= globals.end(); ++it) { + (&(*it->first))->MarkReferences(); + + //The NULL check for the second entry is necessary because for + //some reason the True, False, Boolean, and System classes + //get into the globals map although they shouldn't. Although + //I tried to find out why, I never did... :( They are not entered + //into the map using Universe::SetGlobal and there is no other way + //to enter them into that map.... + if (&(*it->second) != NULL) (&(*it->second))->MarkReferences(); + } + // Get the current frame and mark it. + // Since marking is done recursively, this automatically + // marks the whole stack + pVMFrame currentFrame = _UNIVERSE->GetInterpreter()->GetFrame(); + if (currentFrame != NULL) { + ((pVMObject)currentFrame)->MarkReferences(); + } +} + +void GarbageCollector::mergeFreeSpaces() { + + VMFreeObject* currentEntry = heap->freeListStart; + VMFreeObject* last = NULL; + heap->sizeOfFreeHeap = 0; + while (currentEntry->GetNext() != NULL) { + if((int)currentEntry + (int)currentEntry->GetObjectSize() == + (int)currentEntry->GetNext()) { + int newEntrySize = currentEntry->GetObjectSize() + + currentEntry->GetNext()->GetObjectSize(); + currentEntry->SetObjectSize(newEntrySize); + currentEntry->SetNext(currentEntry->GetNext()->GetNext()); + } else { + heap->sizeOfFreeHeap += currentEntry->GetObjectSize(); + currentEntry->SetPrevious(last); + last = currentEntry; + currentEntry = currentEntry->GetNext(); + } + } + currentEntry->SetPrevious(last); + heap->sizeOfFreeHeap += currentEntry->GetObjectSize(); + +} + +#define _KB(B) (B/1024) +#define _MB(B) ((double)B/(1024.0*1024.0)) + +void GarbageCollector::PrintGCStat() const { + cerr << "-- GC statistics --" << endl; + cerr << "* heap size " << heap->objectSpaceSize << " B (" << + _KB(heap->objectSpaceSize) << " kB, " << + _MB(heap->objectSpaceSize) << " MB)" << endl; + cerr << "* performed " << numCollections << " collections" << endl; +} + +void GarbageCollector::PrintCollectStat() const { + cerr << endl << "[GC " << numCollections << ", " << + heap->numAlloc << " alloc (" << _KB(heap->spcAlloc) << + " kB), " << numLive << " live (" << _KB(spcLive) << + " kB), " << numFreed << " freed (" << _KB(spcFreed) << + " kB)]" << endl; +} + diff --git a/src/memory/GarbageCollector.h b/src/memory/GarbageCollector.h new file mode 100644 index 0000000..0abd1f6 --- /dev/null +++ b/src/memory/GarbageCollector.h @@ -0,0 +1,65 @@ +#pragma once +#ifndef GARBAGECOLLECTOR_H_ +#define GARBAGECOLLECTOR_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "../vmobjects/ObjectFormats.h" +#include "../misc/defs.h" + +class VMObject; +class Heap; + +class GarbageCollector { +public: + GarbageCollector(Heap* h); + ~GarbageCollector(); + void Collect(); + void PrintGCStat() const; + void PrintCollectStat() const; + + +private: + void markReachableObjects(); + void mergeFreeSpaces(); + Heap* heap; + + // + // values for GC statistics + // + uint32_t numCollections; + uint32_t numLive; + uint32_t spcLive; + uint32_t numFreed; + uint32_t spcFreed; + + + +}; + +#endif diff --git a/src/memory/Heap.cpp b/src/memory/Heap.cpp new file mode 100644 index 0000000..d99f931 --- /dev/null +++ b/src/memory/Heap.cpp @@ -0,0 +1,266 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include +#include + +#include "Heap.h" + +#include "../vmobjects/VMObject.h" +#include "../vmobjects/VMFreeObject.h" + +#include "../vm/Universe.h" + +/* + * macro for padding - only word-aligned memory must be allocated + */ +#define PAD_BYTES(N) ((sizeof(void*) - ((N) % sizeof(void*))) % sizeof(void*)) + +Heap* Heap::theHeap = NULL; + +Heap* Heap::GetHeap() { + if (!theHeap) { + _UNIVERSE->ErrorExit("Trying to access uninitialized Heap"); + } + return theHeap; +} + +void Heap::InitializeHeap( int objectSpaceSize ) { + if (theHeap) { + cout << "Warning, reinitializing already initialized Heap, " + << "all data will be lost!" << endl; + delete theHeap; + } + theHeap = new Heap(objectSpaceSize); +} + +void Heap::DestroyHeap() { + if (theHeap) delete theHeap; +} + + + +Heap::Heap(int objectSpaceSize) { + objectSpace = malloc(objectSpaceSize); + if (!objectSpace) { + std::cout << "Failed to allocate the initial "<< objectSpaceSize + << " bytes for the Heap. Panic.\n" << std::endl; + exit(1); + } + memset(objectSpace, 0, objectSpaceSize); + sizeOfFreeHeap = objectSpaceSize; + this->objectSpaceSize = objectSpaceSize; + this->buffersizeForUninterruptable = (int) (objectSpaceSize * 0.1); + + uninterruptableCounter = 0; + numAlloc = 0; + spcAlloc = 0; + numAllocTotal = 0; + freeListStart = (VMFreeObject*) objectSpace; + freeListStart->SetObjectSize(objectSpaceSize); + freeListStart->SetNext(NULL); + freeListStart->SetPrevious(NULL); + freeListStart->SetGCField(-1); + /*freeListStart = (FreeListEntry*) objectSpace; + freeListStart->size = objectSpaceSize; + freeListStart->next = NULL;*/ + gc = new GarbageCollector(this); +} + +Heap::~Heap() { + if (gcVerbosity > 0) { + cout << "-- Heap statistics --" << endl; + cout << "Total number of allocations: " << numAllocTotal << endl; + cout << "Number of allocations since last collection: " + << numAlloc << endl; + std::streamsize p = cout.precision(); + cout.precision(3); + cout << "Used memory: " << spcAlloc << "/" + << this->objectSpaceSize << " (" + << ((double)spcAlloc/(double)this->objectSpaceSize)*100 << "%)" << endl; + cout.precision(p); + gc->PrintGCStat(); + } + free(objectSpace); + +} + +VMObject* Heap::AllocateObject(size_t size) { + //add padding, so objects are word aligned + size_t paddedSize = size + PAD_BYTES(size); + + VMObject* vmo = (VMObject*) Allocate(paddedSize); + + ++numAlloc; + ++numAllocTotal; + spcAlloc += paddedSize; + return vmo; +} + +void* Heap::Allocate(size_t size) { + if (size == 0) return NULL; + if (size < sizeof(VMObject)) { + //this will never happen, as all allocation is done for VMObjects + return internalAllocate(size); + } +#ifdef HEAPDEBUG + std::cout << "allocating: " << (int)size << "bytes" << std::endl; +#endif + //if there is not enough free heap size and we are not inside an uninterruptable + //section of allocation, start garbage collection + if (sizeOfFreeHeap <= buffersizeForUninterruptable && + uninterruptableCounter <= 0) { +#ifdef HEAPDEBUG + cout << "Not enough free memory, only: " << sizeOfFreeHeap + << " bytes left." << endl + << "Starting Garbage Collection" << endl; +#endif + gc->Collect(); + + // + //reset allocation stats + // + numAlloc = 0; + spcAlloc = 0; + } + + VMObject* result = NULL; + VMFreeObject* cur = freeListStart; + VMFreeObject* last = NULL; + while(cur->GetObjectSize() != size && + cur->GetObjectSize() < size+sizeof(VMObject) && + cur->GetNext() != NULL) { + last = cur; + cur = cur->GetNext(); + } + if (cur->GetObjectSize() == size) { + //perfect fit + if (cur == freeListStart) { + freeListStart = cur->GetNext(); + freeListStart->SetPrevious(NULL); + } else { + last->SetNext(cur->GetNext()); + cur->GetNext()->SetPrevious(last); + } + result = cur; + } else if (cur->GetObjectSize() >= size + sizeof(VMFreeObject)) { + //found an entry that is big enough + int oldSize = cur->GetObjectSize(); + VMFreeObject* oldNext = cur->GetNext(); + result = cur; + VMFreeObject* replaceEntry = (VMFreeObject*) ((int)cur + size); + replaceEntry->SetObjectSize(oldSize - size); + replaceEntry->SetGCField(-1); + replaceEntry->SetNext(oldNext); + if (cur == freeListStart) { + freeListStart = replaceEntry; + freeListStart->SetPrevious(NULL); + } else { + last->SetNext(replaceEntry); + replaceEntry->SetPrevious(last); + } + } else { + //problem... might lose data here + cout << "Not enough heap, data loss is possible" << endl; + gc->Collect(); + this->numAlloc = 0; + this->spcAlloc = 0; + result = (VMObject*)this->Allocate(size); + } + + if (result == NULL) { + cout << "alloc failed" << endl; + PrintFreeList(); + _UNIVERSE->ErrorExit("Failed to allocate"); + } + + memset(result, 0, size); + result->SetObjectSize(size); + this->sizeOfFreeHeap -= size; + + return result; + +} + +void Heap::PrintFreeList() { + VMFreeObject* curEntry = freeListStart; + int i =0; + while (curEntry != NULL) { + cout << "i: " << curEntry->GetObjectSize() << endl; + ++i; + curEntry = curEntry->GetNext(); + } +} + +void Heap::Free(void* ptr) { + if ( ((int)ptr < (int) this->objectSpace) && + ((int)ptr > (int) this->objectSpace + this->objectSpaceSize)) { + internalFree(ptr); + } +} + +void Heap::Destroy(VMObject* _object) { + + int freedBytes = _object->GetObjectSize(); + memset(_object, 0, freedBytes); + VMFreeObject* object = (VMFreeObject*) _object; + + //see if there's an adjoining unused object behind this object + VMFreeObject* next = (VMFreeObject*)((int)object + (int)freedBytes); + if (next->GetGCField() == -1) { + //yes, there is, so we can join them + object->SetObjectSize(next->GetObjectSize() + freedBytes); + object->SetNext(next->GetNext()); + next->GetNext()->SetPrevious(object); + VMFreeObject* previous = next->GetPrevious(); + object->SetPrevious(previous); + memset(next, 0, next->GetObjectSize()); + } else { + //no, there is not, so we just put the new unused object as the new freeListStart + object->SetObjectSize(freedBytes); + object->SetNext(freeListStart); + freeListStart->SetPrevious(object); + freeListStart = object; + } + //TODO: find a way to merge unused objects that are before this object +} + +void Heap::internalFree(void* ptr) { + free(ptr); +} + +void* Heap::internalAllocate(size_t size) { + if (size == 0) return NULL; + void* result = malloc(size); + if(!result) { + cout << "Failed to allocate " << size << " Bytes." << endl; + _UNIVERSE->Quit(-1); + } + memset(result, 0, size); + return result; +} diff --git a/src/memory/Heap.h b/src/memory/Heap.h new file mode 100644 index 0000000..beb9669 --- /dev/null +++ b/src/memory/Heap.h @@ -0,0 +1,97 @@ +#pragma once +#ifndef HEAP_H_ +#define HEAP_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include + +#include "GarbageCollector.h" + +#include "../misc/defs.h" + +#include "../vmobjects/ObjectFormats.h" + +class VMObject; +class VMFreeObject; + +//macro to access the heap +#define _HEAP Heap::GetHeap() + +struct FreeListEntry +{ + size_t size; +} ; + + +class Heap +{ + friend class GarbageCollector; + +public: + static Heap* GetHeap(); + static void InitializeHeap(int objectSpaceSize = 1048576); + static void DestroyHeap(); + Heap(int objectSpaceSize = 1048576); + ~Heap(); + VMObject* AllocateObject(size_t size); + void* Allocate(size_t size); + void Free(void* ptr); + void Destroy(VMObject*); + + void StartUninterruptableAllocation() { ++uninterruptableCounter; } ; + void EndUninterruptableAllocation() { --uninterruptableCounter; } ; + + void PrintFreeList(); + + +private: + static Heap* theHeap; + + void internalFree(void* ptr); + void* internalAllocate(size_t size); + + void* objectSpace; + + VMFreeObject* freeListStart; + + + + int objectSpaceSize; + int buffersizeForUninterruptable; + int uninterruptableCounter; + int sizeOfFreeHeap; + + GarbageCollector* gc; + + uint32_t numAlloc; + uint32_t spcAlloc; + uint32_t numAllocTotal; +}; + +#endif diff --git a/src/misc/ExtendedList.h b/src/misc/ExtendedList.h new file mode 100644 index 0000000..65f9927 --- /dev/null +++ b/src/misc/ExtendedList.h @@ -0,0 +1,128 @@ +#pragma once +#ifndef EXTENDEDLIST_H_ +#define EXTENDEDLIST_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include +#include +#include + +template +class ExtendedList { +public: + explicit ExtendedList(); + + void Add(const T& ptr); + void AddIfAbsent(const T& ptr); + void AddAll(const ExtendedList* list); + void PushBack(const T& ptr); + void Clear(); + int Size() const; + T Get(int index); + int IndexOf(const T& needle); + + typedef typename std::list::iterator iterator_t; + typedef typename std::list::const_iterator const_iterator_t; + + iterator_t Begin() { + return theList.begin(); + } + // implement for const objects... + const_iterator_t Begin() const { return theList.begin(); } + +private: + std::list theList; +}; + + +template +ExtendedList::ExtendedList() { + theList.clear(); +} + + +template +void ExtendedList::Add(const T& ptr) { + theList.push_back(ptr); +} + + +template +void ExtendedList::AddAll(const ExtendedList* list) { + theList.merge(list->theList); +} + + +template +void ExtendedList::AddIfAbsent(const T& ptr) { + if (IndexOf(ptr) == -1) Add(ptr); +} + + +template +void ExtendedList::Clear() { + theList.clear(); +} + + +template +T ExtendedList::Get(int index) { + for (iterator_t it = theList.begin(); it!=theList.end(); ++it){ + if (index == 0) return *it; + --index; + } + return NULL; +} + + +template +int ExtendedList::Size() const { + return theList.size(); +} + + +template +int ExtendedList::IndexOf(const T& needle) { + for (iterator_t it = theList.begin(); it!=theList.end(); ++it) { + if (*it == needle) + return distance(theList.begin(), it); + + } + return -1; +} + + +template < class T > +void ExtendedList::PushBack( const T& ptr ) { + theList.push_back(ptr); +} + + +#endif diff --git a/src/misc/debug.h b/src/misc/debug.h new file mode 100644 index 0000000..5000c9b --- /dev/null +++ b/src/misc/debug.h @@ -0,0 +1,109 @@ +#pragma once + +#ifndef DEBUG_H_ +#define DEBUG_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include + + +#define FprintfPass(f,x) \ + va_list ap; \ + va_start(ap, (x)); \ + (void)vfprintf((f), (x), ap); \ + va_end(ap) + + +static inline void DebugPrint(const char* fmt, ...) { + FprintfPass(stderr, fmt); +} + + +static inline void DebugPrefix(const char* prefix) { + DebugPrint("%-6s ", prefix); +} + + +#define DebugPass(x) \ + va_list ap; \ + va_start(ap, (x)); \ + (void)vfprintf(stderr, (x), ap); \ + va_end(ap) + + +static inline void DebugInfo(const char* fmt, ...) { + #ifdef DEBUG + DebugPrefix("INFO:"); + DebugPass(fmt); + #else + (void)fmt; + #endif DEBUG +} + + +static inline void DebugLog(const char* fmt, ...) { + #ifdef DEBUG + DebugPrefix("LOG:"); + DebugPass(fmt); + #else + (void)fmt; + #endif DEBUG +} + + +static inline void DebugWarn(const char* fmt, ...) { + DebugPrefix("WARN:"); + DebugPass(fmt); +} + + +static inline void DebugError(const char* fmt, ...) { + DebugPrefix("ERROR:"); + DebugPass(fmt); +} + + +static inline void DebugDump(const char* fmt, ...) { + DebugPrefix("DUMP:"); + DebugPass(fmt); +} + + +static inline void DebugTrace(const char* fmt, ...) { + DebugPrefix("TRACE:"); + DebugPass(fmt); +} + + +#undef FprintfPass +#undef DebugPass + + +#endif DEBUG_H_ diff --git a/src/misc/defs.h b/src/misc/defs.h new file mode 100644 index 0000000..fef013e --- /dev/null +++ b/src/misc/defs.h @@ -0,0 +1,71 @@ +#pragma once +#ifndef DEFS_H_ +#define DEFS_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +// +// error codes +// + + +#define ERR_SUCCESS 0x0 +#define ERR_FAIL 0x1 +#define ERR_NOMEM 0x2 +#define ERR_PANIC 0xFFFF + +#ifndef INT32_MAX + /*Maximum value of 32-bit integer is 0x7FFF FFFF (2 147 483 647) */ + #define INT32_MAX 0x7FFFFFFF /*2 147 483 647*/ +#endif +#ifndef INT32_MIN + #define INT32_MIN (-2147483647) + +#endif +// +// defs for classpath extraction +// +#define pathSeparator ':' +#define fileSeparator '/' + +typedef std::string StdString; + +#if defined(_MSC_VER) +typedef unsigned long long uint64_t; +typedef long long int64_t; +typedef unsigned long uint32_t; +typedef long int32_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned char uint8_t; +typedef char int8_t; +#endif + + +#endif diff --git a/src/misc/gettimeofday.h b/src/misc/gettimeofday.h new file mode 100644 index 0000000..514d045 --- /dev/null +++ b/src/misc/gettimeofday.h @@ -0,0 +1,81 @@ +#pragma once +#ifndef TIMEHELPER_H_ +#define TIMEHELPER_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include < time.h > + +//This file is only necessary for Visual Studio compatibility +//as sys/time.h is not available using MSVS +#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 +#else + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL +#endif + +struct timezone { + int tz_minuteswest; /* minutes W of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + + + +int gettimeofday(struct timeval *tv, struct timezone *tz) { + FILETIME ft; + unsigned __int64 tmpres = 0; + static int tzflag; + + if (NULL != tv) { + GetSystemTimeAsFileTime(&ft); + + tmpres |= ft.dwHighDateTime; + tmpres <<= 32; + tmpres |= ft.dwLowDateTime; + + /*converting file time to unix epoch*/ + tmpres /= 10; /*convert into microseconds*/ + tmpres -= DELTA_EPOCH_IN_MICROSECS; + tv->tv_sec = (long)(tmpres / 1000000UL); + tv->tv_usec = (long)(tmpres % 1000000UL); + } + + if (NULL != tz) { + if (!tzflag) { + _tzset(); + tzflag++; + } + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } + + return 0; +} + +#endif diff --git a/src/primitives/Array.cpp b/src/primitives/Array.cpp new file mode 100644 index 0000000..2587458 --- /dev/null +++ b/src/primitives/Array.cpp @@ -0,0 +1,84 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "Array.h" + +#include "../primitivesCore/Routine.h" + +#include +#include +#include +#include + +#include + +_Array::_Array() : PrimitiveContainer() +{ + this->SetPrimitive("new_", static_cast( + new Routine<_Array>(this, &_Array::New_))); + this->SetPrimitive("at_", static_cast( + new Routine<_Array>(this, &_Array::At_))); + this->SetPrimitive("at_put_", static_cast( + new Routine<_Array>(this, &_Array::At_Put_))); + this->SetPrimitive("length", static_cast( + new Routine<_Array>(this, &_Array::Length))); +} + +void _Array::At_(pVMObject /*object*/, pVMFrame frame) { + pVMInteger index = (pVMInteger) frame->Pop(); + pVMArray self = (pVMArray) frame->Pop(); + int i = index->GetEmbeddedInteger(); + pVMObject elem = (*self)[i-1]; + frame->Push(elem); +} + + +void _Array::At_Put_(pVMObject /*object*/, pVMFrame frame) { + pVMObject value = frame->Pop(); + pVMInteger index = (pVMInteger)frame->Pop(); + pVMArray self = (pVMArray)frame->GetStackElement(0); + int i = index->GetEmbeddedInteger(); + (*self)[i - 1] = value; +} + + +void _Array::Length(pVMObject /*object*/, pVMFrame frame) { + pVMArray self = (pVMArray) frame->Pop(); + pVMInteger new_int = + _UNIVERSE->NewInteger(self->GetNumberOfIndexableFields()); + frame->Push((pVMObject)new_int); +} + + +void _Array::New_(pVMObject /*object*/, pVMFrame frame) { + pVMInteger length = (pVMInteger)frame->Pop(); + /*pVMClass self = (pVMClass)*/ + frame->Pop(); + int size = length->GetEmbeddedInteger(); + frame->Push((pVMObject) _UNIVERSE->NewArray(size)); +} + diff --git a/src/primitives/Array.h b/src/primitives/Array.h new file mode 100644 index 0000000..ee7823b --- /dev/null +++ b/src/primitives/Array.h @@ -0,0 +1,52 @@ +#pragma once + +#ifndef CORE_ARRAY_H_ +#define CORE_ARRAY_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMObject; +class VMFrame; + +#include "../primitivesCore/PrimitiveContainer.h" + + +class _Array : public PrimitiveContainer +{ +public: + _Array(); + void New_(pVMObject object, pVMFrame frame); + void At_(pVMObject object, pVMFrame frame); + void At_Put_(pVMObject object, pVMFrame frame); + void Length(pVMObject object, pVMFrame frame); +}; + +#endif + + + diff --git a/src/primitives/BigInteger.cpp b/src/primitives/BigInteger.cpp new file mode 100644 index 0000000..7801822 --- /dev/null +++ b/src/primitives/BigInteger.cpp @@ -0,0 +1,234 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include +#include +#include + +#include "../primitivesCore/Routine.h" + +#include "BigInteger.h" + +#include +#include +#include +#include +#include + +#include + + +#define CHECK_BIGINT(object, result) { \ + /* Check second parameter type: */ \ + pVMInteger ptr;\ + if((ptr = DynamicConvert(object)) != NULL) { \ + /* Second operand was Integer*/ \ + int32_t i = ptr->GetEmbeddedInteger(); \ + (result) = _UNIVERSE->NewBigInteger((int64_t)i); \ + } else \ + (result) = (pVMBigInteger)(object); \ +} + +#define PUSH_INT_OR_BIGINT(result) { \ + if(result > INT32_MAX ||result < INT32_MIN) \ + frame->Push((pVMObject)_UNIVERSE->NewBigInteger((result))); \ + else \ + frame->Push((pVMObject)_UNIVERSE->NewInteger((int32_t)(result))); \ +} +//^^DIFFERENT THAN CSOM! Does the CSOM version work at all???????? + + +_BigInteger::_BigInteger( ) : PrimitiveContainer(){ + this->SetPrimitive("plus", static_cast( + new Routine<_BigInteger>(this, &_BigInteger::Plus))); + + this->SetPrimitive("minus", static_cast( + new Routine<_BigInteger>(this, &_BigInteger::Minus))); + + this->SetPrimitive("star", static_cast( + new Routine<_BigInteger>(this, &_BigInteger::Star))); + + this->SetPrimitive("slash", static_cast( + new Routine<_BigInteger>(this, &_BigInteger::Slash))); + + this->SetPrimitive("percent", static_cast( + new Routine<_BigInteger>(this, &_BigInteger::Percent))); + + this->SetPrimitive("and", static_cast( + new Routine<_BigInteger>(this, &_BigInteger::And))); + + this->SetPrimitive("equal", static_cast( + new Routine<_BigInteger>(this, &_BigInteger::Equal))); + + this->SetPrimitive("lowerthan", static_cast( + new Routine<_BigInteger>(this, &_BigInteger::Lowerthan))); + + this->SetPrimitive("asString", static_cast( + new Routine<_BigInteger>(this, &_BigInteger::AsString))); + + this->SetPrimitive("sqrt", static_cast( + new Routine<_BigInteger>(this, &_BigInteger::Sqrt))); + +} + + +void _BigInteger::Plus(pVMObject /*object*/, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMBigInteger right = NULL; + pVMBigInteger left = (pVMBigInteger)frame->Pop(); + + CHECK_BIGINT(rightObj, right); + + // Do operation and perform conversion to Integer if required + int64_t result = left->GetEmbeddedInteger() + + right->GetEmbeddedInteger(); + PUSH_INT_OR_BIGINT(result); +} + + +void _BigInteger::Minus(pVMObject /*object*/, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMBigInteger right = NULL; + pVMBigInteger left = (pVMBigInteger)frame->Pop(); + + CHECK_BIGINT(rightObj, right); + + // Do operation and perform conversion to Integer if required + int64_t result = left->GetEmbeddedInteger() + - right->GetEmbeddedInteger(); + PUSH_INT_OR_BIGINT(result); +} + + +void _BigInteger::Star(pVMObject /*object*/, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMBigInteger right = NULL; + pVMBigInteger left = (pVMBigInteger)frame->Pop(); + + CHECK_BIGINT(rightObj, right); + + // Do operation and perform conversion to Integer if required + int64_t result = left->GetEmbeddedInteger() + * right->GetEmbeddedInteger(); + PUSH_INT_OR_BIGINT(result); +} + + +void _BigInteger::Slash(pVMObject /*object*/, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMBigInteger right = NULL; + pVMBigInteger left = (pVMBigInteger)frame->Pop(); + + CHECK_BIGINT(rightObj, right); + + // Do operation and perform conversion to Integer if required + int64_t result = left->GetEmbeddedInteger() + / right->GetEmbeddedInteger(); + PUSH_INT_OR_BIGINT(result); +} + + +void _BigInteger::Percent(pVMObject /*object*/, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMBigInteger right = NULL; + pVMBigInteger left = (pVMBigInteger)frame->Pop(); + + CHECK_BIGINT(rightObj, right); + + // Do operation and perform conversion to Integer if required + pVMBigInteger result = _UNIVERSE->NewBigInteger( left->GetEmbeddedInteger() + % right->GetEmbeddedInteger()); + + frame->Push((pVMObject) result); +} + + +void _BigInteger::And(pVMObject /*object*/, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMBigInteger right = NULL; + pVMBigInteger left = (pVMBigInteger)frame->Pop(); + + CHECK_BIGINT(rightObj, right); + + // Do operation and perform conversion to Integer if required + pVMBigInteger result = _UNIVERSE->NewBigInteger( left->GetEmbeddedInteger() + & right->GetEmbeddedInteger()); + + frame->Push((pVMObject) result); +} + + +void _BigInteger::Equal(pVMObject /*object*/, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMBigInteger right = NULL; + pVMBigInteger left = (pVMBigInteger)frame->Pop(); + + CHECK_BIGINT(rightObj, right); + + // Do operation: + if(left->GetEmbeddedInteger() == right->GetEmbeddedInteger()) + frame->Push(trueObject); + else + frame->Push(falseObject); +} + + +void _BigInteger::Lowerthan(pVMObject /*object*/, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMBigInteger right = NULL; + pVMBigInteger left = (pVMBigInteger)frame->Pop(); + + CHECK_BIGINT(rightObj, right); + + // Do operation: + if(left->GetEmbeddedInteger() < right->GetEmbeddedInteger()) + frame->Push(trueObject); + else + frame->Push(falseObject); + +} + + +void _BigInteger::AsString(pVMObject /*object*/, pVMFrame frame) { + pVMBigInteger self = (pVMBigInteger)frame->Pop(); + + int64_t bigint = self->GetEmbeddedInteger(); + ostringstream Str; + Str << bigint; + frame->Push((pVMObject)_UNIVERSE->NewString(Str.str().c_str())); + +} + + +void _BigInteger::Sqrt(pVMObject /*object*/, pVMFrame frame) { + pVMBigInteger self = (pVMBigInteger)frame->Pop(); + int64_t i = self->GetEmbeddedInteger(); + frame->Push((pVMObject)_UNIVERSE->NewDouble(sqrt((double)i))); +} + + diff --git a/src/primitives/BigInteger.h b/src/primitives/BigInteger.h new file mode 100644 index 0000000..f729c9e --- /dev/null +++ b/src/primitives/BigInteger.h @@ -0,0 +1,58 @@ +#pragma once + +#ifndef CORE_BIGINTEGER_H_ +#define CORE_BIGINTEGER_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMObject; +class VMFrame; + +#include "../primitivesCore/PrimitiveContainer.h" + +class _BigInteger : public PrimitiveContainer +{ +public: + _BigInteger(); + void Plus(pVMObject object, pVMFrame frame); + void Minus(pVMObject object, pVMFrame frame); + void Star(pVMObject object, pVMFrame frame); + void Slash(pVMObject object, pVMFrame frame); + void Percent(pVMObject object, pVMFrame frame); + void And(pVMObject object, pVMFrame frame); + void Equal(pVMObject object, pVMFrame frame); + void Lowerthan(pVMObject object, pVMFrame frame); + void AsString(pVMObject object, pVMFrame frame); + void Sqrt(pVMObject object, pVMFrame frame); + +}; + +#endif + + + diff --git a/src/primitives/Block.cpp b/src/primitives/Block.cpp new file mode 100644 index 0000000..f369c85 --- /dev/null +++ b/src/primitives/Block.cpp @@ -0,0 +1,73 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "Block.h" + +#include "../primitivesCore/Routine.h" + +#include +#include + +#include + + + +void _Block::Value(pVMObject /*object*/, pVMFrame /*frame*/) { + // intentionally left blank +} + + +void _Block::Value_(pVMObject /*object*/, pVMFrame /*frame*/) { + // intentionally left blank +} + + +void _Block::Value_with_(pVMObject /*object*/, pVMFrame /*frame*/) { + // intentionally left blank +} + + +void _Block::Restart(pVMObject /*object*/, pVMFrame frame) { + frame->SetBytecodeIndex(0); + frame->ResetStackPointer(); +} + +_Block::_Block( ) : PrimitiveContainer() { + this->SetPrimitive("value", static_cast( + new Routine<_Block>(this, &_Block::Value))); + + this->SetPrimitive("restart", static_cast( + new Routine<_Block>(this, &_Block::Restart))); + + this->SetPrimitive("value_", static_cast( + new Routine<_Block>(this, &_Block::Value_))); + + this->SetPrimitive("value_with_", static_cast( + new Routine<_Block>(this, &_Block::Value_with_))); +} + + diff --git a/src/primitives/Block.h b/src/primitives/Block.h new file mode 100644 index 0000000..28fbce1 --- /dev/null +++ b/src/primitives/Block.h @@ -0,0 +1,48 @@ +#pragma once + +#ifndef CORE_BLOCK_H_ +#define CORE_BLOCK_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMObject; +class VMFrame; + +#include "../primitivesCore/PrimitiveContainer.h" + +class _Block : public PrimitiveContainer +{ +public: + _Block(); + void Value(pVMObject object, pVMFrame frame); + void Restart(pVMObject object, pVMFrame frame); + void Value_(pVMObject object, pVMFrame frame); + void Value_with_(pVMObject object, pVMFrame frame); +}; + +#endif diff --git a/src/primitives/Class.cpp b/src/primitives/Class.cpp new file mode 100644 index 0000000..3d0f8b5 --- /dev/null +++ b/src/primitives/Class.cpp @@ -0,0 +1,47 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "Class.h" + +#include "../primitivesCore/Routine.h" + +#include +#include +#include + +#include + + + +_Class::_Class( ) : PrimitiveContainer() { + this->SetPrimitive("new", new Routine<_Class>(this, &_Class::New)); +} + +void _Class::New(pVMObject /*object*/, pVMFrame frame) { + pVMClass self = (pVMClass)frame->Pop(); + frame->Push(_UNIVERSE->NewInstance(self)); +} diff --git a/src/primitives/Class.h b/src/primitives/Class.h new file mode 100644 index 0000000..4885da1 --- /dev/null +++ b/src/primitives/Class.h @@ -0,0 +1,47 @@ +#pragma once + +#ifndef CORE_CLASS_H_ +#define CORE_CLASS_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMObject; +class VMFrame; + +#include "../primitivesCore/PrimitiveContainer.h" + +class _Class : public PrimitiveContainer +{ +public: + _Class(); + void New(pVMObject object, pVMFrame frame); +}; + + + +#endif diff --git a/src/primitives/Core.cpp b/src/primitives/Core.cpp new file mode 100644 index 0000000..44d4de0 --- /dev/null +++ b/src/primitives/Core.cpp @@ -0,0 +1,149 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include + +#include + +#include "Array.h" +#include "BigInteger.h" +#include "Block.h" +#include "Class.h" +#include "Double.h" +#include "Integer.h" +#include "Object.h" +#include "String.h" +#include "Symbol.h" +#include "System.h" + + +#include "../primitivesCore/PrimitiveContainer.h" +#include "../primitivesCore/PrimitiveLoader.h" + +#if defined (_MSC_VER) +#include "Core.h" +#endif + + +static PrimitiveLoader* loader = NULL; + +//"Constructor" +//#define __DEBUG +extern "C" void setup() { + if (!loader) { +#ifdef __DEBUG + cout << "Setting up the Core library" << endl; +#endif + //Initialize loader + loader = new PrimitiveLoader(); + loader->AddPrimitiveObject("Array", + static_cast(new _Array())); + + loader->AddPrimitiveObject("BigInteger", + static_cast(new _BigInteger())); + + loader->AddPrimitiveObject("Block", + static_cast(new _Block())); + + loader->AddPrimitiveObject("Class", + static_cast(new _Class())); + + loader->AddPrimitiveObject("Double", + static_cast(new _Double())); + + loader->AddPrimitiveObject("Integer", + static_cast(new _Integer())); + + loader->AddPrimitiveObject("Object", + static_cast(new _Object())); + + loader->AddPrimitiveObject("String", + static_cast(new _String())); + + loader->AddPrimitiveObject("Symbol", + static_cast(new _Symbol())); + + loader->AddPrimitiveObject("System", + static_cast(new _System())); + } +} + +extern "C" bool supportsClass(const char* name) { + if (!loader) setup(); + return loader->SupportsClass(name); +} + + + +extern "C" void tearDown() { + + if (loader) delete loader; + +} + +//"Factory method" +extern "C" PrimitiveRoutine* create(const StdString& cname, const StdString& fname) { + +#ifdef __DEBUG + cout << "Loading PrimitiveContainer: " << cname << "::" << fname << endl; +#endif + if (!loader) setup(); + return loader->GetPrimitiveRoutine(cname, fname); +} + +/* Lib initialization */ +#ifdef __GNUC__ +void init(void) __attribute__((constructor)); +void fini(void) __attribute__((destructor)); +#else +void _init(void); +void _fini(void); +#pragma init _init +#pragma fini _fini +#endif __GNUC__ + + +#ifdef __GNUC__ +void init(void) +#else +void _init(void) +#endif __GNUC__ +{ + // Call init funcions. + setup(); + +} + + +#ifdef __GNUC__ +void fini(void) +#else +void _fini(void) +#endif __GNUC__ +{ + tearDown(); +} diff --git a/src/primitives/Core.h b/src/primitives/Core.h new file mode 100644 index 0000000..7189a2b --- /dev/null +++ b/src/primitives/Core.h @@ -0,0 +1,40 @@ +#pragma once +#ifndef CORE_H_ +#define CORE_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +//This header file is only necessary for Visual Studio compilation +#include "../primitivesCore/Routine.h" + +extern "C" void setup(); +extern "C" bool supportsClass(const char* name); +extern "C" void tearDown(); +extern "C" PrimitiveRoutine* create(const StdString& cname, const StdString& fname); + +#endif \ No newline at end of file diff --git a/src/primitives/Double.cpp b/src/primitives/Double.cpp new file mode 100644 index 0000000..522dfc1 --- /dev/null +++ b/src/primitives/Double.cpp @@ -0,0 +1,185 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "Double.h" +#include "../primitivesCore/Routine.h" + +/* + * This function coerces any right-hand parameter to a double, regardless of its + * true nature. This is to make sure that all Double operations return Doubles. + */ +double _Double::coerceDouble(pVMObject x) { + pVMDouble dx; + pVMInteger ix; + pVMBigInteger bix; + if((dx = DynamicConvert(x)) != NULL) + return dx->GetEmbeddedDouble(); + else if((ix = DynamicConvert(x)) != NULL) + return (double)ix->GetEmbeddedInteger(); + else if((bix = DynamicConvert(x)) != NULL) + return (double)bix->GetEmbeddedInteger(); + else + _UNIVERSE->ErrorExit("Attempt to apply Double operation to non-number."); + + return 0.0f; +} + + +/* + * The following standard functionality is performed in all arithmetic + * operations: extract the right-hand operand by coercing it to a double, and + * extract the left-hand operand as an immediate Double. Afterwards, left and + * right are prepared for the operation. + */ +#define PREPARE_OPERANDS \ + double right = coerceDouble(frame->Pop()); \ + pVMDouble leftObj = (pVMDouble)frame->Pop(); \ + double left = leftObj->GetEmbeddedDouble(); + + +void _Double::Plus(pVMObject /*object*/, pVMFrame frame) { + PREPARE_OPERANDS; + frame->Push((pVMObject)_UNIVERSE->NewDouble(left + right)); +} + + +void _Double::Minus(pVMObject /*object*/, pVMFrame frame) { + PREPARE_OPERANDS; + frame->Push((pVMObject)_UNIVERSE->NewDouble(left - right)); +} + + +void _Double::Star(pVMObject /*object*/, pVMFrame frame) { + PREPARE_OPERANDS; + frame->Push((pVMObject)_UNIVERSE->NewDouble(left * right)); +} + + +void _Double::Slashslash(pVMObject /*object*/, pVMFrame frame) { + PREPARE_OPERANDS; + frame->Push((pVMObject)_UNIVERSE->NewDouble(left / right)); +} + + +void _Double::Percent(pVMObject /*object*/, pVMFrame frame) { + PREPARE_OPERANDS; + frame->Push(_UNIVERSE->NewDouble((double)((int64_t)left % + (int64_t)right))); +} +void _Double::And(pVMObject /*object*/, pVMFrame frame) { + PREPARE_OPERANDS; + frame->Push(_UNIVERSE->NewDouble((double)((int64_t)left & + (int64_t)right))); +} + + + +/* + * This function implements strict (bit-wise) equality and is therefore + * inaccurate. + */ +void _Double::Equal(pVMObject /*object*/, pVMFrame frame) { + PREPARE_OPERANDS; + if(left == right) + frame->Push(trueObject); + else + frame->Push(falseObject); +} + + +void _Double::Lowerthan(pVMObject /*object*/, pVMFrame frame) { + PREPARE_OPERANDS; + if(left < right) + frame->Push(trueObject); + else + frame->Push(falseObject); +} + + +void _Double::AsString(pVMObject /*object*/, pVMFrame frame) { + pVMDouble self = (pVMDouble)frame->Pop(); + + double dbl = self->GetEmbeddedDouble(); + ostringstream Str; + Str.precision(17); + Str << dbl; + frame->Push( (pVMObject)_UNIVERSE->NewString( Str.str().c_str() ) ); +} + + +void _Double::Sqrt(pVMObject /*object*/, pVMFrame frame) { + pVMDouble self = (pVMDouble)frame->Pop(); + pVMDouble result = _UNIVERSE->NewDouble( sqrt(self->GetEmbeddedDouble()) ); + frame->Push((pVMObject)result); +} + +_Double::_Double( ) : PrimitiveContainer() { + this->SetPrimitive("plus", new + Routine<_Double>(this, &_Double::Plus)); + + this->SetPrimitive("minus", new + Routine<_Double>(this, &_Double::Minus)); + + this->SetPrimitive("star", new + Routine<_Double>(this, &_Double::Star)); + + this->SetPrimitive("slashslash", new + Routine<_Double>(this, &_Double::Slashslash)); + + this->SetPrimitive("percent", new + Routine<_Double>(this, &_Double::Percent)); + + this->SetPrimitive("and", new + Routine<_Double>(this, &_Double::And)); + + this->SetPrimitive("equal", new + Routine<_Double>(this, &_Double::Equal)); + + this->SetPrimitive("lowerthan", new + Routine<_Double>(this, &_Double::Lowerthan)); + + this->SetPrimitive("asString", new + Routine<_Double>(this, &_Double::AsString)); + + this->SetPrimitive("sqrt", new + Routine<_Double>(this, &_Double::Sqrt)); +} + diff --git a/src/primitives/Double.h b/src/primitives/Double.h new file mode 100644 index 0000000..a663a68 --- /dev/null +++ b/src/primitives/Double.h @@ -0,0 +1,57 @@ +#pragma once + +#ifndef CORE_DOUBLE_H_ +#define CORE_DOUBLE_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMObject; +class VMFrame; + +#include "../primitivesCore/PrimitiveContainer.h" + +class _Double : public PrimitiveContainer +{ +public: + _Double(); + void Plus(pVMObject object, pVMFrame frame); + void Minus(pVMObject object, pVMFrame frame); + void Star(pVMObject object, pVMFrame frame); + void Slashslash(pVMObject object, pVMFrame frame); + void Percent(pVMObject object, pVMFrame frame); + void And(pVMObject object, pVMFrame frame); + void Equal(pVMObject object, pVMFrame frame); + void Lowerthan(pVMObject object, pVMFrame frame); + void AsString(pVMObject object, pVMFrame frame); + void Sqrt(pVMObject object, pVMFrame frame); +private: + double coerceDouble(pVMObject x); +}; + + +#endif diff --git a/src/primitives/Integer.cpp b/src/primitives/Integer.cpp new file mode 100644 index 0000000..dd9fb7c --- /dev/null +++ b/src/primitives/Integer.cpp @@ -0,0 +1,323 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "Integer.h" +#include "../primitivesCore/Routine.h" + +/* + * This macro performs a coercion check to BigInteger and Double. Depending on + * the right-hand operand, an Integer operation will have to be resent as a + * BigInteger or Double operation (those types impose themselves on the result + * of an Integer operation). + */ +#define CHECK_COERCION(obj,receiver,op) { \ + if(DynamicConvert(obj) != NULL) { \ + resendAsBigInteger( \ + object, (op), (receiver), (pVMBigInteger)(obj)); \ + return; \ + } else if(DynamicConvert(obj) != NULL) { \ + resendAsDouble( \ + object, (op), (receiver), (pVMDouble)(obj)); \ + return; \ + } \ +} + +_Integer::_Integer( ) : PrimitiveContainer() { + srand((unsigned) time(NULL)) ; + this->SetPrimitive("plus", new + Routine<_Integer>(this, &_Integer::Plus)); + + this->SetPrimitive("minus", new + Routine<_Integer>(this, &_Integer::Minus)); + + this->SetPrimitive("star", new + Routine<_Integer>(this, &_Integer::Star)); + + this->SetPrimitive("slash", new + Routine<_Integer>(this, &_Integer::Slash)); + + this->SetPrimitive("slashslash", new + Routine<_Integer>(this, &_Integer::Slashslash)); + + this->SetPrimitive("percent", new + Routine<_Integer>(this, &_Integer::Percent)); + + this->SetPrimitive("and", new + Routine<_Integer>(this, &_Integer::And)); + this->SetPrimitive("equal", new + Routine<_Integer>(this, &_Integer::Equal)); + + this->SetPrimitive("lowerthan", + new Routine<_Integer>(this, &_Integer::Lowerthan)); + this->SetPrimitive("asString", + new Routine<_Integer>(this, &_Integer::AsString)); + + this->SetPrimitive("sqrt", + new Routine<_Integer>(this, &_Integer::Sqrt)); + + this->SetPrimitive("atRandom", + new Routine<_Integer>(this, &_Integer::AtRandom)); +} + +// +// private functions for Integer +// + + +void _Integer::pushResult(pVMObject /*object*/, pVMFrame frame, + int64_t result) { + int32_t i32min = INT32_MIN; + // Check with integer bounds and push: + if(result > INT32_MAX || result < i32min) + frame->Push((pVMObject)_UNIVERSE->NewBigInteger(result)); + else + frame->Push((pVMObject)_UNIVERSE->NewInteger((int32_t)result)); +} + + +void _Integer::resendAsBigInteger(pVMObject /*object*/, + const char* op, + pVMInteger left, pVMBigInteger right) { + // Construct left value as BigInteger: + pVMBigInteger leftBigInteger = + _UNIVERSE->NewBigInteger((int64_t)left->GetEmbeddedInteger()); + + // Resend message: + pVMObject operands[] = { (pVMObject)right }; + + leftBigInteger->Send(op, operands, 1); + // no reference +} + + +void _Integer::resendAsDouble(pVMObject /*object*/, const char* op, + pVMInteger left, pVMDouble right +) { + pVMDouble leftDouble = + _UNIVERSE->NewDouble((double)left->GetEmbeddedInteger()); + pVMObject operands[] = { (pVMObject)right }; + + leftDouble->Send(op, operands, 1); +} + + + +// +// arithmetic operations +// + + +void _Integer::Plus(pVMObject object, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMInteger left = (pVMInteger)frame->Pop(); + + CHECK_COERCION(rightObj, left, "+"); + + // Do operation: + pVMInteger right = (pVMInteger)rightObj; + + int64_t result = (int64_t)left->GetEmbeddedInteger() + + (int64_t)right->GetEmbeddedInteger(); + pushResult(object, frame, result); +} + + +void _Integer::Minus(pVMObject object, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMInteger left = (pVMInteger)frame->Pop(); + + CHECK_COERCION(rightObj, left, "-"); + + // Do operation: + pVMInteger right = (pVMInteger)rightObj; + + int64_t result = (int64_t)left->GetEmbeddedInteger() - + (int64_t)right->GetEmbeddedInteger(); + pushResult(object, frame, result); +} + + +void _Integer::Star(pVMObject object, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMInteger left = (pVMInteger)frame->Pop(); + + CHECK_COERCION(rightObj, left, "*"); + + // Do operation: + pVMInteger right = (pVMInteger)rightObj; + + int64_t result = (int64_t)left->GetEmbeddedInteger() * + (int64_t)right->GetEmbeddedInteger(); + pushResult(object, frame, result); +} + + +void _Integer::Slashslash(pVMObject object, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMInteger left = (pVMInteger)frame->Pop(); + + CHECK_COERCION(rightObj, left, "/"); + + // Do operation: + pVMInteger right = (pVMInteger)rightObj; + + double result = (double)left->GetEmbeddedInteger() / + (double)right->GetEmbeddedInteger(); + frame->Push(_UNIVERSE->NewDouble(result)); +} + + +void _Integer::Slash(pVMObject object, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMInteger left = (pVMInteger)frame->Pop(); + + CHECK_COERCION(rightObj, left, "/"); + + // Do operation: + pVMInteger right = (pVMInteger)rightObj; + + int64_t result = (int64_t)left->GetEmbeddedInteger() / + (int64_t)right->GetEmbeddedInteger(); + pushResult(object, frame, result); +} + + +void _Integer::Percent(pVMObject object, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMInteger left = (pVMInteger)frame->Pop(); + + CHECK_COERCION(rightObj, left, "%"); + + // Do operation: + pVMInteger right = (pVMInteger)rightObj; + + int64_t result = (int64_t)left->GetEmbeddedInteger() % + (int64_t)right->GetEmbeddedInteger(); + pushResult(object, frame, result); +} + + +void _Integer::And(pVMObject object, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMInteger left = (pVMInteger)frame->Pop(); + + CHECK_COERCION(rightObj, left, "&"); + + // Do operation: + pVMInteger right = (pVMInteger)rightObj; + + int64_t result = (int64_t)left->GetEmbeddedInteger() & + (int64_t)right->GetEmbeddedInteger(); + pushResult(object, frame, result); +} + + +void _Integer::Equal(pVMObject object, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMInteger left = (pVMInteger)frame->Pop(); + + CHECK_COERCION(rightObj, left, "="); + + pVMInteger iright; + pVMDouble dright; + if((iright = DynamicConvert(rightObj)) != NULL) { + // Second operand was Integer: + + if(left->GetEmbeddedInteger() + == iright->GetEmbeddedInteger()) + frame->Push(trueObject); + else + frame->Push(falseObject); + } else if((dright = DynamicConvert(rightObj)) != NULL) { + + if((double)left->GetEmbeddedInteger() + == dright->GetEmbeddedDouble()) + frame->Push(trueObject); + else + frame->Push(falseObject); + } + else + frame->Push(falseObject); +} + + +void _Integer::Lowerthan(pVMObject object, pVMFrame frame) { + pVMObject rightObj = frame->Pop(); + pVMInteger left = (pVMInteger)frame->Pop(); + + CHECK_COERCION(rightObj, left, "<"); + + pVMInteger right = (pVMInteger)rightObj; + + if(left->GetEmbeddedInteger() < right->GetEmbeddedInteger()) + frame->Push(trueObject); + else + frame->Push(falseObject); +} + + +void _Integer::AsString(pVMObject /*object*/, pVMFrame frame) { + pVMInteger self = (pVMInteger)frame->Pop(); + + int32_t integer = self->GetEmbeddedInteger(); + ostringstream Str; + Str << integer; + frame->Push( (pVMObject)_UNIVERSE->NewString( Str.str() ) ); +} + + +void _Integer::Sqrt(pVMObject /*object*/, pVMFrame frame) { + pVMInteger self = (pVMInteger)frame->Pop(); + double result = sqrt((double)self->GetEmbeddedInteger()); + frame->Push((pVMObject)_UNIVERSE->NewDouble(result)); +} + + +void _Integer::AtRandom(pVMObject /*object*/, pVMFrame frame) { + pVMInteger self = (pVMInteger)frame->Pop(); + int32_t result = (self->GetEmbeddedInteger() * rand())%INT32_MAX; + frame->Push((pVMObject) _UNIVERSE->NewInteger(result)); +} + + + diff --git a/src/primitives/Integer.h b/src/primitives/Integer.h new file mode 100644 index 0000000..3f02b4d --- /dev/null +++ b/src/primitives/Integer.h @@ -0,0 +1,72 @@ +#pragma once + +#ifndef CORE_INTEGER_H_ +#define CORE_INTEGER_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMObject; +class VMFrame; +class VMInteger; +class VMBigInteger; +class VMDouble; + +#include "../primitivesCore/PrimitiveContainer.h" + +class _Integer : public PrimitiveContainer +{ + +public: + + void Plus(pVMObject object, pVMFrame frame); + void Minus(pVMObject object, pVMFrame frame); + void Star(pVMObject object, pVMFrame frame); + void Slash(pVMObject object, pVMFrame frame); + void Slashslash(pVMObject object, pVMFrame frame); + void Percent(pVMObject object, pVMFrame frame); + void And(pVMObject object, pVMFrame frame); + void Equal(pVMObject object, pVMFrame frame); + void Lowerthan(pVMObject object, pVMFrame frame); + void AsString(pVMObject object, pVMFrame frame); + void Sqrt(pVMObject object, pVMFrame frame); + void AtRandom(pVMObject object, pVMFrame frame); + + _Integer(void); + +private: + void pushResult(pVMObject object, pVMFrame frame, int64_t result); + void resendAsBigInteger(pVMObject object, + const char* op, + pVMInteger left, pVMBigInteger right); + void resendAsDouble(pVMObject object, const char* op, + pVMInteger left, pVMDouble right); + +}; + + +#endif diff --git a/src/primitives/Object.cpp b/src/primitives/Object.cpp new file mode 100644 index 0000000..73558bc --- /dev/null +++ b/src/primitives/Object.cpp @@ -0,0 +1,66 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include + +#include + +#include "../primitivesCore/Routine.h" +#include "Object.h" + +_Object::_Object( ) : PrimitiveContainer() { + this->SetPrimitive("equalequal", new + Routine<_Object>(this, &_Object::Equalequal)); + + this->SetPrimitive("objectSize", new + Routine<_Object>(this, &_Object::ObjectSize)); + + this->SetPrimitive("hashcode", new + Routine<_Object>(this, &_Object::Hashcode)); +} + +void _Object::Equalequal(pVMObject /*object*/, pVMFrame frame) { + pVMObject op1 = frame->Pop(); + pVMObject op2 = frame->Pop(); + + frame->Push( op1 == op2 ? trueObject : falseObject ); +} + + +void _Object::ObjectSize(pVMObject /*object*/, pVMFrame frame) { + pVMObject self = frame->Pop(); + + frame->Push( (pVMObject)_UNIVERSE->NewInteger(self->GetObjectSize()) ); +} + + +void _Object::Hashcode(pVMObject /*object*/, pVMFrame frame) { + pVMObject self = frame->Pop(); + frame->Push( (pVMObject)_UNIVERSE->NewInteger(self->GetHash()) ); +} + diff --git a/src/primitives/Object.h b/src/primitives/Object.h new file mode 100644 index 0000000..7085c74 --- /dev/null +++ b/src/primitives/Object.h @@ -0,0 +1,46 @@ +#pragma once + +#ifndef CORE_OBJECT_H_ +#define CORE_OBJECT_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMObject; +class VMFrame; +#include "../primitivesCore/PrimitiveContainer.h" + +class _Object : public PrimitiveContainer +{ +public: + _Object(); + void Equalequal(pVMObject object, pVMFrame frame); + void ObjectSize(pVMObject object, pVMFrame frame); + void Hashcode(pVMObject object, pVMFrame frame); +}; + +#endif diff --git a/src/primitives/String.cpp b/src/primitives/String.cpp new file mode 100644 index 0000000..27ca135 --- /dev/null +++ b/src/primitives/String.cpp @@ -0,0 +1,129 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include + +#include +#include +#include +#include + +#include + +#include + +#include "String.h" +#include "../primitivesCore/Routine.h" + +_String::_String( ) : PrimitiveContainer() { + this->SetPrimitive("concatenate_", new + Routine<_String>(this, &_String::Concatenate_)); + + this->SetPrimitive("asSymbol", new + Routine<_String>(this, &_String::AsSymbol)); + + this->SetPrimitive("hashcode", new + Routine<_String>(this, &_String::Hashcode)); + + this->SetPrimitive("length", new + Routine<_String>(this, &_String::Length)); + + this->SetPrimitive("equal", new + Routine<_String>(this, &_String::Equal)); + + this->SetPrimitive("primSubstringFrom_To_", new + Routine<_String>(this, &_String::PrimSubstringFrom_To_)); +} + +void _String::Concatenate_(pVMObject /*object*/, pVMFrame frame) { + + pVMString arg = (pVMString)frame->Pop(); + pVMString self = (pVMString)frame->Pop(); + StdString a = arg->GetChars(); + StdString s = self->GetChars(); + + StdString result = s + a; + + frame->Push((pVMObject)_UNIVERSE->NewString(result)); +} + + +void _String::AsSymbol(pVMObject /*object*/, pVMFrame frame) { + pVMString self = (pVMString)frame->Pop(); + StdString result = self->GetStdString(); + frame->Push((pVMObject)_UNIVERSE->SymbolFor(result)); +} + + +void _String::Hashcode(pVMObject /*object*/, pVMFrame frame) { + pVMString self = (pVMString)frame->Pop(); + frame->Push((pVMObject)_UNIVERSE->NewInteger(self->GetHash())); +} + + +void _String::Length(pVMObject /*object*/, pVMFrame frame) { + pVMString self = (pVMString)frame->Pop(); + + size_t len = self->GetStringLength(); + frame->Push(_UNIVERSE->NewInteger((int32_t)len)); +} + + +void _String::Equal(pVMObject /*object*/, pVMFrame frame) { + pVMObject op1 = frame->Pop(); + pVMString op2 = (pVMString)frame->Pop(); + + if(op1->GetClass() == op2->GetClass()) { + + StdString s1 = ((pVMString)op1)->GetStdString(); + StdString s2 = op2->GetStdString(); + + if(s1 == s2) { + frame->Push(trueObject); + return; + } + } + frame->Push(falseObject); +} + + +void _String::PrimSubstringFrom_To_(pVMObject /*object*/, pVMFrame frame) { + pVMInteger end = (pVMInteger)frame->Pop(); + pVMInteger start = (pVMInteger)frame->Pop(); + + pVMString self = (pVMString)frame->Pop(); + + StdString str = self->GetStdString(); + int s = start->GetEmbeddedInteger(); + int e = end->GetEmbeddedInteger(); + + StdString result = str.substr(s, e - s); + + frame->Push((pVMObject) _UNIVERSE->NewString(result)); +} + + diff --git a/src/primitives/String.h b/src/primitives/String.h new file mode 100644 index 0000000..8374f91 --- /dev/null +++ b/src/primitives/String.h @@ -0,0 +1,52 @@ +#pragma once + +#ifndef CORE_STRING_H_ +#define CORE_STRING_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMObject; +class VMFrame; +#include "../primitivesCore/PrimitiveContainer.h" + +class _String : public PrimitiveContainer +{ +public: + _String(); + void Concatenate_(pVMObject object, pVMFrame frame); + void AsSymbol(pVMObject object, pVMFrame frame); + void Hashcode(pVMObject object, pVMFrame frame); + void Length(pVMObject object, pVMFrame frame); + void Equal(pVMObject object, pVMFrame frame); + void PrimSubstringFrom_To_(pVMObject object, pVMFrame frame); +}; + + + +#endif + diff --git a/src/primitives/Symbol.cpp b/src/primitives/Symbol.cpp new file mode 100644 index 0000000..f6039da --- /dev/null +++ b/src/primitives/Symbol.cpp @@ -0,0 +1,53 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "../misc/defs.h" + +#include "../vmobjects/VMObject.h" +#include "../vmobjects/VMFrame.h" +#include "../vmobjects/VMSymbol.h" + +#include "../vm/Universe.h" +#include "../primitivesCore/Routine.h" +#include "Symbol.h" + +_Symbol* Symbol; + +void _Symbol::AsString(pVMObject /*object*/, pVMFrame frame) { + pVMSymbol sym = (pVMSymbol) frame->Pop(); + + StdString str = sym->GetStdString(); + frame->Push((pVMObject)_UNIVERSE->NewString(str)); +} + +_Symbol::_Symbol( ) : PrimitiveContainer() { + this->SetPrimitive("asString", new + Routine<_Symbol>(this, &_Symbol::AsString)); +} + + + diff --git a/src/primitives/Symbol.h b/src/primitives/Symbol.h new file mode 100644 index 0000000..706247b --- /dev/null +++ b/src/primitives/Symbol.h @@ -0,0 +1,47 @@ +#pragma once + +#ifndef CORE_SYMBOL_H_ +#define CORE_SYMBOL_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMObject; +class VMFrame; +#include "../primitivesCore/PrimitiveContainer.h" + +class _Symbol : public PrimitiveContainer +{ +public: + _Symbol(); + void AsString(pVMObject object, pVMFrame frame); +}; + +#endif + + + diff --git a/src/primitives/System.cpp b/src/primitives/System.cpp new file mode 100644 index 0000000..012d43c --- /dev/null +++ b/src/primitives/System.cpp @@ -0,0 +1,159 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include + +#include + +#include +#include +#include +#include + +#include + +#include "System.h" +#include "../primitivesCore/Routine.h" + +#if defined(__GNUC__) + + #include + +#else + + #include + +#endif + +_System* System_; + +void _System::Global_(pVMObject /*object*/, pVMFrame frame) { + pVMSymbol arg = (pVMSymbol)frame->Pop(); + /*pVMObject self = */ + frame->Pop(); + pVMObject result = _UNIVERSE->GetGlobal(arg); + + frame->Push( result ? result : nilObject); +} + + +void _System::Global_put_(pVMObject /*object*/, pVMFrame frame) { + pVMObject value = frame->Pop(); + pVMSymbol arg = (pVMSymbol)frame->Pop(); + _UNIVERSE->SetGlobal(arg, value); +} + + +void _System::Load_(pVMObject /*object*/, pVMFrame frame) { + pVMSymbol arg = (pVMSymbol)frame->Pop(); + /*pVMObject self = */ + frame->Pop(); + pVMClass result = _UNIVERSE->LoadClass(arg); + + frame->Push( result? (pVMObject)result : nilObject); +} + + +void _System::Exit_(pVMObject /*object*/, pVMFrame frame) { + pVMInteger err = (pVMInteger)frame->Pop(); + int32_t err_no = err->GetEmbeddedInteger(); + + if(err_no != ERR_SUCCESS) + frame->PrintStackTrace(); + _UNIVERSE->Quit(err_no); +} + + +void _System::PrintString_(pVMObject /*object*/, pVMFrame frame) { + pVMString arg = (pVMString)frame->Pop(); + std::string str = arg->GetStdString(); + cout << str; +} + + +void _System::PrintNewline(pVMObject /*object*/, pVMFrame /*frame*/) { + cout << endl; +} + + +void _System::Time(pVMObject /*object*/, pVMFrame frame) { + /*pVMObject self = */ + frame->Pop(); + timeval* now = new timeval(); + + gettimeofday(now, NULL); + + long long diff = + ((now->tv_sec - start_time->tv_sec) * 1000) + //seconds + ((now->tv_usec - start_time->tv_usec) / 1000); // µseconds + + frame->Push((pVMObject)_UNIVERSE->NewInteger((int32_t)diff)); + + delete(now); +} + + +_System::_System(void) : PrimitiveContainer() { + start_time = new timeval(); + gettimeofday(start_time, NULL); + + this->SetPrimitive("global_", + static_cast(new + Routine<_System>(this, &_System::Global_))); + + this->SetPrimitive("global_put_", + static_cast(new + Routine<_System>(this, &_System::Global_put_))); + + this->SetPrimitive("load_", + static_cast(new + Routine<_System>(this, &_System::Load_))); + + this->SetPrimitive("exit_", + static_cast(new + Routine<_System>(this, &_System::Exit_))); + + this->SetPrimitive("printString_", + static_cast(new + Routine<_System>(this, &_System::PrintString_))); + + this->SetPrimitive("printNewline", + static_cast(new + Routine<_System>(this, &_System::PrintNewline))); + + this->SetPrimitive("time", + static_cast(new + Routine<_System>(this, &_System::Time))); + +} + +_System::~_System() +{ + delete(start_time); +} + + diff --git a/src/primitives/System.h b/src/primitives/System.h new file mode 100644 index 0000000..d6d9809 --- /dev/null +++ b/src/primitives/System.h @@ -0,0 +1,62 @@ +#pragma once + +#ifndef CORE_SYSTEM_H_ +#define CORE_SYSTEM_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMObject; +class VMFrame; +#include "../primitivesCore/PrimitiveContainer.h" + + +struct timeval; + +class _System : public PrimitiveContainer +{ +public: + _System(void); + virtual ~_System(); + + void Global_(pVMObject object, pVMFrame frame); + void Global_put_(pVMObject object, pVMFrame frame); + void Load_(pVMObject object, pVMFrame frame); + void Exit_(pVMObject object, pVMFrame frame); + void PrintString_(pVMObject object, pVMFrame frame); + void PrintNewline(pVMObject object, pVMFrame frame); + void Time(pVMObject object, pVMFrame frame); + + +private: + timeval* start_time; +}; + +#endif + + + diff --git a/src/primitivesCore/PrimitiveContainer.cpp b/src/primitivesCore/PrimitiveContainer.cpp new file mode 100644 index 0000000..a1e4e0b --- /dev/null +++ b/src/primitivesCore/PrimitiveContainer.cpp @@ -0,0 +1,46 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "PrimitiveContainer.h" + +PrimitiveContainer::PrimitiveContainer() { + methods = new map(); +} + +PrimitiveContainer::~PrimitiveContainer() +{ + delete methods; +} + +void PrimitiveContainer::SetPrimitive( const char* name, PrimitiveRoutine* routine ) +{ + (*methods)[StdString(name)] = routine; +} + +PrimitiveRoutine* PrimitiveContainer::GetPrimitive(const std::string& routineName) { + return (*methods)[routineName]; +} diff --git a/src/primitivesCore/PrimitiveContainer.h b/src/primitivesCore/PrimitiveContainer.h new file mode 100644 index 0000000..f9f1a4e --- /dev/null +++ b/src/primitivesCore/PrimitiveContainer.h @@ -0,0 +1,61 @@ +#pragma once +#ifndef PRIMITIVECONTAINER_H_ +#define PRIMITIVECONTAINER_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include + +#include + +///Base class for all container objects holding SOM++ primitives. +//Primitive container classes need to initialize a std::map in order to map smalltalk message names to the method +//to call. +class PrimitiveContainer { + +public: + PrimitiveContainer(); + virtual ~PrimitiveContainer(); + + ///Every derived Class must use this method to initialize the methods + //map with the mapping of a StdString with the smalltalk message + //name and the corresponding functor object. The abstract functor object + //class is defined in vmobjects/PrimitiveRoutine. Basically, the only + //requirement for those objects is to implement: + // virtual void operator()(pVMObject, pVMFrame) + virtual void SetPrimitive(const char* name, PrimitiveRoutine* routine); + + virtual PrimitiveRoutine* GetPrimitive(const std::string& routineName); + +private: + std::map* methods; +}; + +#endif diff --git a/src/primitivesCore/PrimitiveLoader.cpp b/src/primitivesCore/PrimitiveLoader.cpp new file mode 100644 index 0000000..cb7ffb4 --- /dev/null +++ b/src/primitivesCore/PrimitiveLoader.cpp @@ -0,0 +1,68 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "PrimitiveLoader.h" +#include "PrimitiveContainer.h" + +#include + + +PrimitiveLoader::PrimitiveLoader() { + primitiveObjects = map(); +} + +PrimitiveLoader::~PrimitiveLoader() { + map::iterator it = primitiveObjects.begin(); + for (; it != primitiveObjects.end(); ++it) { + delete it->second; + } + +} + +void PrimitiveLoader::AddPrimitiveObject( const char* name, PrimitiveContainer* prim) { + primitiveObjects[StdString(name)] = prim; +} + +bool PrimitiveLoader::SupportsClass( const char* name ) { + return primitiveObjects[StdString(name)] != NULL; +} + +PrimitiveRoutine* PrimitiveLoader::GetPrimitiveRoutine( const std::string& cname, const std::string& mname ) { + PrimitiveRoutine* result; + PrimitiveContainer* primitive = primitiveObjects[cname]; + if (!primitive) { + cout << "Primitive object not found for name: " << cname << endl; + return NULL; + } + result = primitive->GetPrimitive(mname); + if (!result) { + cout << "method " << mname << " not found in class" << cname << endl; + return NULL; + } + return result; +} + diff --git a/src/primitivesCore/PrimitiveLoader.h b/src/primitivesCore/PrimitiveLoader.h new file mode 100644 index 0000000..f701467 --- /dev/null +++ b/src/primitivesCore/PrimitiveLoader.h @@ -0,0 +1,65 @@ +#pragma once +#ifndef PRIMITIVESLOADER_H_ +#define PRIMITIVESLOADER_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include + +class PrimitiveContainer; +class PrimitiveRoutine; + +///Core class for primitive loading. +//In order to implement new primitive libraries, you can use this class +//to implement the "create" factory method (of course you can do something +//totally different, if you chose...) +// +//Functions that are expected to be exported by the library are: +//bool supportsClass(const char* name) +//void tearDown() +//PrimitiveRoutine* create(const StdString& cname, const StdString& fname) +// +//The expected file extension is ".csp". +//Libraries have to take care of initializing any needed data or data structures. +//When using the PrimitiveLoader class that is the the std::map primitiveObjects. +//Initialize it by calling the AddPrimitiveObject method, in order to map the +//name of the smalltalk class to the corresponding PrimitiveContainer object. +class PrimitiveLoader { +public: + PrimitiveLoader(); + virtual ~PrimitiveLoader(); + virtual PrimitiveRoutine* + GetPrimitiveRoutine(const std::string& cname, const std::string& mname); + virtual void AddPrimitiveObject(const char*, PrimitiveContainer*); + virtual bool SupportsClass(const char*); +private: + std::map primitiveObjects; +}; + +#endif PRIMITIVESCORE_H_ diff --git a/src/primitivesCore/Routine.h b/src/primitivesCore/Routine.h new file mode 100644 index 0000000..6a5dcb3 --- /dev/null +++ b/src/primitivesCore/Routine.h @@ -0,0 +1,60 @@ +#pragma once +#ifndef ROUTINE_H_ +#define ROUTINE_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include + +///Implementation for a functor class with PrimitiveRoutine as base class. +//It stores an object and a pointer to one of its methods. It is invoked +//by calling the Routine's poerator "()". +template class Routine : public PrimitiveRoutine +{ +private: + void (TClass::*fpt)(pVMObject, pVMFrame); // pointer to member function + TClass* pt2Object; // pointer to object + +public: + + // constructor - takes pointer to an object and pointer to a member and stores + // them in two private variables + Routine(TClass* _pt2Object, void(TClass::*_fpt)(pVMObject, pVMFrame)) : + PrimitiveRoutine() { + pt2Object = _pt2Object; + fpt=_fpt; + }; + + // override operator "()" + virtual void operator()(pVMObject obj, pVMFrame frm) { + (*pt2Object.*fpt)(obj, frm);// execute member function + }; + +}; + +#endif diff --git a/src/primitivesCore/resource.h b/src/primitivesCore/resource.h new file mode 100644 index 0000000..1f2251c --- /dev/null +++ b/src/primitivesCore/resource.h @@ -0,0 +1,3 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by app.rc diff --git a/src/vm/Shell.cpp b/src/vm/Shell.cpp new file mode 100644 index 0000000..99bf89b --- /dev/null +++ b/src/vm/Shell.cpp @@ -0,0 +1,144 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include + +#include "Universe.h" +#include "Shell.h" + +#include "../vmobjects/VMMethod.h" +#include "../vmobjects/VMClass.h" +#include "../vmobjects/VMFrame.h" +#include "../vmobjects/VMObject.h" +#include "../vmobjects/VMInvokable.h" +#include "../vmobjects/VMPointerConverter.h" + +// maximal length of an input line from the shell +#define INPUT_MAX_SIZE BUFSIZ + +// some constants for assembling Smalltalk code +#define SHELL_PREFIX "Shell_Class_" +#define SHELL_PART_1 " = (run: it = ( | tmp | tmp := (" +#define SHELL_PART_2 "). 'it = ' print. ^tmp println) )" + + +Shell::Shell() { + bootstrapMethod = NULL; +} + + +Shell::Shell(pVMMethod bsm) { + this->bootstrapMethod = bsm; +} + + +Shell::~Shell() { + // TODO +} + + +void Shell::Start() { +#define QUIT_CMD "system exit" +#define QUIT_CMD_L 11 + 1 + + if (bootstrapMethod == NULL) { + _UNIVERSE->ErrorExit("Shell needs bootstrap method!"); + } + // the statement to evaluate + char inbuf[INPUT_MAX_SIZE]; + int bytecodeIndex, counter = 0; + pVMFrame currentFrame; + pVMClass runClass; + pVMObject it = nilObject; // last evaluation result. + + cout << "SOM Shell. Type \"" << QUIT_CMD << "\" to exit.\n"; + + // Create a fake bootstrap frame + currentFrame = _UNIVERSE->GetInterpreter()->PushNewFrame(this->GetBootstrapMethod()); + // Remember the first bytecode index, e.g. index of the halt instruction + bytecodeIndex = currentFrame->GetBytecodeIndex(); + + /** + * Main Shell Loop + */ + while(!cin.eof()) { + // initialize empty strings + StdString statement; + StdString inp; + + cout << "---> "; + // Read a statement from the keyboard + // and avoid buffer overflow. + + cin.getline(inbuf, INPUT_MAX_SIZE); + + inp = StdString(inbuf); + + if (inp.length() == 0) continue; + + // Generate a temporary class with a run method + stringstream ss; + ss << SHELL_PREFIX << counter << SHELL_PART_1 << inp << SHELL_PART_2; + statement = ss.str(); + + ++counter; + runClass = _UNIVERSE->LoadShellClass(statement); + // Compile and load the newly generated class + if(runClass == NULL) { + cout << "can't compile statement."; + continue; + } + + currentFrame = _UNIVERSE->GetInterpreter()->GetFrame(); + + // Go back, so we will evaluate the bootstrap frames halt + // instruction again + currentFrame->SetBytecodeIndex(bytecodeIndex); + + // Create and push a new instance of our class on the stack + currentFrame->Push(_UNIVERSE->NewInstance(runClass)); + + // Push the old value of "it" on the stack + currentFrame->Push(it); + + // Lookup the run: method + pVMInvokable initialize = + DynamicConvert(runClass->LookupInvokable( + _UNIVERSE->SymbolFor("run:"))); + + // Invoke the run method + (*initialize)(currentFrame); + + // Start the Interpreter + + _UNIVERSE->GetInterpreter()->Start(); + + // Save the result of the run method + it = currentFrame->Pop(); + } +} + diff --git a/src/vm/Shell.h b/src/vm/Shell.h new file mode 100644 index 0000000..ec1e459 --- /dev/null +++ b/src/vm/Shell.h @@ -0,0 +1,46 @@ +#pragma once +#ifndef SHELL_H_ +#define SHELL_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMMethod; + +class Shell { +public: + Shell(); + Shell(pVMMethod); + ~Shell(); + void SetBootstrapMethod(pVMMethod bsm) { bootstrapMethod = bsm; } ; + pVMMethod GetBootstrapMethod() const { return bootstrapMethod; } ; + void Start(); +private: + pVMMethod bootstrapMethod; +}; + +#endif diff --git a/src/vm/Universe.cpp b/src/vm/Universe.cpp new file mode 100644 index 0000000..d03e436 --- /dev/null +++ b/src/vm/Universe.cpp @@ -0,0 +1,705 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include +#include + +#include "Universe.h" +#include "Shell.h" + +#include "../vmobjects/VMSymbol.h" +#include "../vmobjects/VMObject.h" +#include "../vmobjects/VMMethod.h" +#include "../vmobjects/VMClass.h" +#include "../vmobjects/VMFrame.h" +#include "../vmobjects/VMArray.h" +#include "../vmobjects/VMBlock.h" +#include "../vmobjects/VMDouble.h" +#include "../vmobjects/VMInteger.h" +#include "../vmobjects/VMString.h" +#include "../vmobjects/VMBigInteger.h" +#include "../vmobjects/VMEvaluationPrimitive.h" +#include "../vmobjects/Symboltable.h" +#include "../vmobjects/VMPointerConverter.h" + +#include "../interpreter/bytecodes.h" + +#include "../compiler/Disassembler.h" +#include "../compiler/SourcecodeCompiler.h" + +// Here we go: + +short dumpBytecodes; +short gcVerbosity; + + +Universe* Universe::theUniverse = NULL; + +pVMObject nilObject; +pVMObject trueObject; +pVMObject falseObject; + +pVMClass objectClass; +pVMClass classClass; +pVMClass metaClassClass; + +pVMClass nilClass; +pVMClass integerClass; +pVMClass bigIntegerClass; +pVMClass arrayClass; +pVMClass methodClass; +pVMClass symbolClass; +pVMClass frameClass; +pVMClass primitiveClass; +pVMClass stringClass; +pVMClass systemClass; +pVMClass blockClass; +pVMClass doubleClass; + +//Singleton accessor +Universe* Universe::GetUniverse() { + if (!theUniverse) { + ErrorExit("Trying to access uninitialized Universe, exiting."); + } + return theUniverse; +} + + +Universe* Universe::operator->() { + if (!theUniverse) { + ErrorExit("Trying to access uninitialized Universe, exiting."); + } + return theUniverse; +} + + +void Universe::Start(int argc, char** argv) { + theUniverse = new Universe(); + theUniverse->initialize(argc, argv); +} + + +void Universe::Quit(int err) { + if (theUniverse) delete(theUniverse); + + exit(err); +} + + +void Universe::ErrorExit( const char* err) { + cout << "Runtime error: " << err << endl; + Quit(ERR_FAIL); +} + +vector Universe::handleArguments( int argc, char** argv ) { + + vector vmArgs = vector(); + dumpBytecodes = 0; + gcVerbosity = 0; + for (int i = 1; i < argc ; ++i) { + + if (strncmp(argv[i], "-cp", 3) == 0) { + if ((argc == i + 1) || classPath.size() > 0) + printUsageAndExit(argv[0]); + setupClassPath(StdString(argv[++i])); + } else if (strncmp(argv[i], "-d", 2) == 0) { + ++dumpBytecodes; + } else if (strncmp(argv[i], "-g", 2) == 0) { + ++gcVerbosity; + } else if (argv[i][0] == '-' && argv[i][1] == 'H') { + int heap_size = atoi(argv[i] + 2); + heapSize = heap_size; + } else if ((strncmp(argv[i], "-h", 2) == 0) || + (strncmp(argv[i], "--help", 6) == 0)) { + printUsageAndExit(argv[0]); + } else { + vector extPathTokens = vector(2); + StdString tmpString = StdString(argv[i]); + if (this->getClassPathExt(extPathTokens, tmpString) == + ERR_SUCCESS) { + this->addClassPath(extPathTokens[0]); + } + //Different from CSOM!!!: + //In CSOM there is an else, where the original filename is pushed into the vm_args. + //But unlike the class name in extPathTokens (extPathTokens[1]) that could + //still have the .som suffix though. + //So in SOM++ getClassPathExt will strip the suffix and add it to extPathTokens + //even if there is no new class path present. So we can in any case do the following: + vmArgs.push_back(extPathTokens[1]); + } + } + addClassPath(StdString(".")); + + return vmArgs; +} + +int Universe::getClassPathExt(vector& tokens,const StdString& arg ) const { +#define EXT_TOKENS 2 + int result = ERR_SUCCESS; + int fpIndex = arg.find_last_of(fileSeparator); + int ssepIndex = arg.find(".som"); + + if (fpIndex == StdString::npos) { //no new path + //different from CSOM (see also HandleArguments): + //we still want to strip the suffix from the filename, so + //we set the start to -1, in order to start the substring + //from character 0. npos is -1 too, but this is to make sure + fpIndex = -1; + //instead of returning here directly, we have to remember that + //there is no new class path and return it later + result = ERR_FAIL; + } else tokens[0] = arg.substr(0, fpIndex); + + //adding filename (minus ".som" if present) to second slot + ssepIndex = ( (ssepIndex != StdString::npos) && (ssepIndex > fpIndex)) ? + (ssepIndex - 1) : + arg.length(); + tokens[1] = arg.substr(fpIndex + 1, ssepIndex - (fpIndex)); + return result; +} + + +int Universe::setupClassPath( const StdString& cp ) { + try { + std::stringstream ss ( cp ); + StdString token; + + int i = 0; + while( getline(ss, token, pathSeparator) ) { + classPath.push_back(token); + ++i; + } + + return ERR_SUCCESS; + } catch(std::exception e){ + return ERR_FAIL; + } +} + + +int Universe::addClassPath( const StdString& cp ) { + classPath.push_back(cp); + return ERR_SUCCESS; +} + + +void Universe::printUsageAndExit( char* executable ) const { + cout << "Usage: " << executable << " [-options] [args...]" << endl << endl; + cout << "where options include:" << endl; + cout << " -cp " << endl; + cout << " set search path for application classes" << endl; + cout << " -d enable disassembling (twice for tracing)" << endl; + cout << " -g enable garbage collection details:" << endl << + " 1x - print statistics when VM shuts down" << endl << + " 2x - print statistics upon each collection" << endl << + " 3x - print statistics and dump _HEAP upon each " << endl << + "collection" << endl; + cout << " -Hx set the _HEAP size to x MB (default: 1 MB)" << endl; + cout << " -h show this help" << endl; + + Quit(ERR_SUCCESS); +} + + +Universe::Universe(){}; + + +void Universe::initialize(int _argc, char** _argv) { + heapSize = 1048576; + + vector argv = this->handleArguments(_argc, _argv); + + Heap::InitializeHeap(heapSize); + heap = _HEAP; + + symboltable = new Symboltable(); + compiler = new SourcecodeCompiler(); + interpreter = new Interpreter(); + + InitializeGlobals(); + + pVMObject systemObject = NewInstance(systemClass); + + this->SetGlobal(SymbolForChars("nil"), nilObject); + this->SetGlobal(SymbolForChars("true"), trueObject); + this->SetGlobal(SymbolForChars("false"), falseObject); + this->SetGlobal(SymbolForChars("system"), systemObject); + this->SetGlobal(SymbolForChars("System"), systemClass); + this->SetGlobal(SymbolForChars("Block"), blockClass); + + pVMMethod bootstrapMethod = NewMethod(SymbolForChars("bootstrap"), 1, 0); + bootstrapMethod->SetBytecode(0, BC_HALT); + bootstrapMethod->SetNumberOfLocals(0); + + bootstrapMethod->SetMaximumNumberOfStackElements(2); + bootstrapMethod->SetHolder(systemClass); + + if (argv.size() == 0) { + Shell* shell = new Shell(bootstrapMethod); + shell->Start(); + return; + } + + /* only trace bootstrap if the number of cmd-line "-d"s is > 2 */ + short trace = 2 - dumpBytecodes; + if(!(trace > 0)) dumpBytecodes = 1; + + pVMArray argumentsArray = _UNIVERSE->NewArrayFromArgv(argv); + + pVMFrame bootstrapFrame = interpreter->PushNewFrame(bootstrapMethod); + bootstrapFrame->Push(systemObject); + bootstrapFrame->Push((pVMObject)argumentsArray); + + pVMInvokable initialize = + DynamicConvert( + systemClass->LookupInvokable(this->SymbolForChars("initialize:"))); + (*initialize)(bootstrapFrame); + + // reset "-d" indicator + if(!(trace>0)) dumpBytecodes = 2 - trace; + + interpreter->Start(); +} + + +Universe::~Universe() { + if (interpreter) + delete(interpreter); + if (compiler) + delete(compiler); + if (_HEAP) + Heap::DestroyHeap(); + if (symboltable) + delete(symboltable); +} + +void Universe::InitializeGlobals() { + // + //allocate nil object + // + nilObject = new (_HEAP) VMObject; + nilObject->SetField(0, nilObject); + + metaClassClass = NewMetaclassClass(); + + objectClass = NewSystemClass(); + nilClass = NewSystemClass(); + classClass = NewSystemClass(); + arrayClass = NewSystemClass(); + symbolClass = NewSystemClass(); + methodClass = NewSystemClass(); + integerClass = NewSystemClass(); + bigIntegerClass = NewSystemClass(); + frameClass = NewSystemClass(); + primitiveClass = NewSystemClass(); + stringClass = NewSystemClass(); + doubleClass = NewSystemClass(); + + nilObject->SetClass(nilClass); + + InitializeSystemClass(objectClass, NULL, "Object"); + InitializeSystemClass(classClass, objectClass, "Class"); + InitializeSystemClass(metaClassClass, classClass, "Metaclass"); + InitializeSystemClass(nilClass, objectClass, "Nil"); + InitializeSystemClass(arrayClass, objectClass, "Array"); + InitializeSystemClass(methodClass, arrayClass, "Method"); + InitializeSystemClass(symbolClass, objectClass, "Symbol"); + InitializeSystemClass(integerClass, objectClass, "Integer"); + InitializeSystemClass(bigIntegerClass, objectClass, + "BigInteger"); + InitializeSystemClass(frameClass, arrayClass, "Frame"); + InitializeSystemClass(primitiveClass, objectClass, + "Primitive"); + InitializeSystemClass(stringClass, objectClass, "String"); + InitializeSystemClass(doubleClass, objectClass, "Double"); + + LoadSystemClass(objectClass); + LoadSystemClass(classClass); + LoadSystemClass(metaClassClass); + LoadSystemClass(nilClass); + LoadSystemClass(arrayClass); + LoadSystemClass(methodClass); + LoadSystemClass(symbolClass); + LoadSystemClass(integerClass); + LoadSystemClass(bigIntegerClass); + LoadSystemClass(frameClass); + LoadSystemClass(primitiveClass); + LoadSystemClass(stringClass); + LoadSystemClass(doubleClass); + + blockClass = LoadClass(_UNIVERSE->SymbolForChars("Block")); + + trueObject = NewInstance(_UNIVERSE->LoadClass(_UNIVERSE->SymbolForChars("True"))); + falseObject = NewInstance(_UNIVERSE->LoadClass(_UNIVERSE->SymbolForChars("False"))); + + systemClass = LoadClass(_UNIVERSE->SymbolForChars("System")); +} + +void Universe::Assert( bool value) const { + if (!value) { + cout << "Assertion failed" << endl; + } + +} + + +pVMClass Universe::GetBlockClass() const { + return blockClass; +} + + +pVMClass Universe::GetBlockClassWithArgs( int numberOfArguments) { + this->Assert(numberOfArguments < 10); + + ostringstream Str; + Str << "Block" << numberOfArguments ; + StdString blockName(Str.str()); + pVMSymbol name = SymbolFor(blockName); + + if (HasGlobal(name)) + return (pVMClass)GetGlobal(name); + + pVMClass result = LoadClassBasic(name, NULL); + + result->AddInstancePrimitive(new (_HEAP) VMEvaluationPrimitive(numberOfArguments) ); + + SetGlobal(name, (pVMObject) result); + + return result; +} + + + +pVMObject Universe::GetGlobal( pVMSymbol name) { + if (HasGlobal(name)) + return (pVMObject)globals[name]; + + return NULL; +} + + +bool Universe::HasGlobal( pVMSymbol name) { + if (globals[name] != NULL) return true; + else return false; +} + + +void Universe::InitializeSystemClass( pVMClass systemClass, + pVMClass superClass, const char* name) { + StdString s_name(name); + + if (superClass != NULL) { + systemClass->SetSuperClass(superClass); + pVMClass sysClassClass = systemClass->GetClass(); + pVMClass superClassClass = superClass->GetClass(); + sysClassClass->SetSuperClass(superClassClass); + } else { + pVMClass sysClassClass = systemClass->GetClass(); + sysClassClass->SetSuperClass(classClass); + } + + pVMClass sysClassClass = systemClass->GetClass(); + + systemClass->SetInstanceFields(NewArray(0)); + sysClassClass->SetInstanceFields(NewArray(0)); + + systemClass->SetInstanceInvokables(NewArray(0)); + sysClassClass->SetInstanceInvokables(NewArray(0)); + + systemClass->SetName(SymbolFor(s_name)); + ostringstream Str; + Str << s_name << " class"; + StdString classClassName(Str.str()); + sysClassClass->SetName(SymbolFor(classClassName)); + + SetGlobal(systemClass->GetName(), (pVMObject)systemClass); + + +} + + +pVMClass Universe::LoadClass( pVMSymbol name) { + if (HasGlobal(name)) + return DynamicConvert(GetGlobal(name)); + + pVMClass result = LoadClassBasic(name, NULL); + + if (!result) { + cout << "can\'t load class " << name->GetStdString() << endl; + Universe::Quit(ERR_FAIL); + } + + if (result->HasPrimitives() || result->GetClass()->HasPrimitives()) + result->LoadPrimitives(classPath); + + return result; +} + + +pVMClass Universe::LoadClassBasic( pVMSymbol name, pVMClass systemClass) { + StdString s_name = name->GetStdString(); + //cout << s_name.c_str() << endl; + pVMClass result; + + for (vector::iterator i = classPath.begin(); + i != classPath.end(); ++i) { + result = compiler->CompileClass(*i, name->GetStdString(), systemClass); + if (result) { + if (dumpBytecodes) { + Disassembler::Dump(result->GetClass()); + Disassembler::Dump(result); + } + return result; + } + + } + return NULL; +} + + +pVMClass Universe::LoadShellClass( StdString& stmt) { + pVMClass result = compiler->CompileClassString(stmt, NULL); + if(dumpBytecodes) + Disassembler::Dump(result); + return result; +} + + +void Universe::LoadSystemClass( pVMClass systemClass) { + pVMClass result = + LoadClassBasic(systemClass->GetName(), systemClass); + StdString s = systemClass->GetName()->GetStdString(); + + if (!result) { + cout << "Can\'t load system class: " << s; + Universe::Quit(ERR_FAIL); + } + + if (result->HasPrimitives() || result->GetClass()->HasPrimitives()) + result->LoadPrimitives(classPath); +} + + +pVMArray Universe::NewArray( int size) const { + int additionalBytes = size*sizeof(pVMObject); + pVMArray result = new (_HEAP, additionalBytes) VMArray(size); + result->SetClass(arrayClass); + return result; +} + + +pVMArray Universe::NewArrayFromArgv( const vector& argv) const { + pVMArray result = NewArray(argv.size()); + int j = 0; + for (vector::const_iterator i = argv.begin(); + i != argv.end(); ++i) { + (*result)[j] = NewString(*i); + ++j; + } + + return result; +} + + +pVMArray Universe::NewArrayList(ExtendedList& list ) const { + int size = list.Size(); + pVMArray result = NewArray(size); + + if (result) { + for (int i = 0; i < size; ++i) { + pVMObject elem = list.Get(i); + + (*result)[i] = elem; + } + } + return result; +} + + +pVMBigInteger Universe::NewBigInteger( int64_t value) const { + pVMBigInteger result = new (_HEAP) VMBigInteger(value); + result->SetClass(bigIntegerClass); + + return result; +} + + +pVMBlock Universe::NewBlock( pVMMethod method, pVMFrame context, int arguments) { + pVMBlock result = new (_HEAP) VMBlock; + result->SetClass(this->GetBlockClassWithArgs(arguments)); + + result->SetMethod(method); + result->SetContext(context); + + return result; +} + + +pVMClass Universe::NewClass( pVMClass classOfClass) const { + int numFields = classOfClass->GetNumberOfInstanceFields(); + pVMClass result; + int additionalBytes = numFields * sizeof(pVMObject); + if (numFields) result = new (_HEAP, additionalBytes) VMClass(numFields); + else result = new (_HEAP) VMClass; + + result->SetClass(classOfClass); + + return result; +} + + +pVMDouble Universe::NewDouble( double value) const { + pVMDouble result = new (_HEAP) VMDouble(value); + result->SetClass(doubleClass); + return result; +} + + +pVMFrame Universe::NewFrame( pVMFrame previousFrame, pVMMethod method) const { + int length = method->GetNumberOfArguments() + + method->GetNumberOfLocals()+ + method->GetMaximumNumberOfStackElements(); + + int additionalBytes = length * sizeof(pVMObject); + pVMFrame result = new (_HEAP, additionalBytes) VMFrame(length); + result->SetClass(frameClass); + + result->SetMethod(method); + + if (previousFrame != NULL) + result->SetPreviousFrame(previousFrame); + + result->ResetStackPointer(); + result->SetBytecodeIndex(0); + + return result; +} + + +pVMObject Universe::NewInstance( pVMClass classOfInstance) const { + //the number of fields for allocation. We have to calculate the clazz + //field out of this, because it is already taken care of by VMObject + int numOfFields = classOfInstance->GetNumberOfInstanceFields() - 1; + //the additional space needed is calculated from the number of fields + int additionalBytes = numOfFields * sizeof(pVMObject); + pVMObject result = new (_HEAP, additionalBytes) VMObject(numOfFields); + result->SetClass(classOfInstance); + return result; +} + +pVMInteger Universe::NewInteger( int32_t value) const { + pVMInteger result = new (_HEAP) VMInteger(value); + result->SetClass(integerClass); + return result; +} + +pVMClass Universe::NewMetaclassClass() const { + pVMClass result = new (_HEAP) VMClass; + result->SetClass(new (_HEAP) VMClass); + + pVMClass mclass = result->GetClass(); + mclass->SetClass(result); + + return result; +} + + +pVMMethod Universe::NewMethod( pVMSymbol signature, + size_t numberOfBytecodes, size_t numberOfConstants) const { + //Method needs space for the bytecodes and the pointers to the constants + int additionalBytes = numberOfBytecodes + + numberOfConstants*sizeof(pVMObject); + pVMMethod result = new (_HEAP,additionalBytes) + VMMethod(numberOfBytecodes, numberOfConstants); + result->SetClass(methodClass); + + result->SetSignature(signature); + + return result; +} + +pVMString Universe::NewString( const StdString& str) const { + return NewString(str.c_str()); +} + +pVMString Universe::NewString( const char* str) const { + //string needs space for str.length characters plus one byte for '\0' + int additionalBytes = strlen(str) + 1; + pVMString result = new (_HEAP, additionalBytes) VMString(str); + result->SetClass(stringClass); + + return result; +} + +pVMSymbol Universe::NewSymbol( const StdString& str) { + return NewSymbol(str.c_str()); +} + +pVMSymbol Universe::NewSymbol( const char* str ) { + //symbol needs space for str.length characters plus one byte for '\0' + int additionalBytes = strlen(str) + 1; + pVMSymbol result = new (_HEAP, additionalBytes) VMSymbol(str); + result->SetClass(symbolClass); + + symboltable->insert(result); + + return result; +} + + +pVMClass Universe::NewSystemClass() const { + pVMClass systemClass = new (_HEAP) VMClass(); + + systemClass->SetClass(new (_HEAP) VMClass()); + pVMClass mclass = systemClass->GetClass(); + + mclass->SetClass(metaClassClass); + + return systemClass; +} + + +pVMSymbol Universe::SymbolFor( const StdString& str) { + return SymbolForChars(str.c_str()); + +} + + +pVMSymbol Universe::SymbolForChars( const char* str) { + pVMSymbol result = symboltable->lookup(str); + + return (result != NULL) ? + result : + NewSymbol(str); +} + + +void Universe::SetGlobal(pVMSymbol name, pVMObject val) { + globals[name] = val; +} diff --git a/src/vm/Universe.h b/src/vm/Universe.h new file mode 100644 index 0000000..013f3af --- /dev/null +++ b/src/vm/Universe.h @@ -0,0 +1,176 @@ +#pragma once +#ifndef UNIVERSE_H_ +#define UNIVERSE_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +//#define __DEBUG +#include +#include + +#include "../misc/defs.h" +#include "../misc/ExtendedList.h" + +#include "../vmobjects/ObjectFormats.h" +#include "../vmobjects/VMPointer.h" + +#include "../interpreter/Interpreter.h" + +#include "../memory/Heap.h" + + +class VMObject; +class VMSymbol; +class VMClass; +class VMFrame; +class VMArray; +class VMBlock; +class VMDouble; +class VMInteger; +class VMMethod; +class VMString; +class VMBigInteger; +class Symboltable; +class SourcecodeCompiler; + +//Convenience macro for Singleton access +#define _UNIVERSE Universe::GetUniverse() + +// for runtime debug +extern short dumpBytecodes; +extern short gcVerbosity; + +//global VMObjects +extern pVMObject nilObject; +extern pVMObject trueObject; +extern pVMObject falseObject; + +extern pVMClass objectClass; +extern pVMClass classClass; +extern pVMClass metaClassClass; + +extern pVMClass nilClass; +extern pVMClass integerClass; +extern pVMClass bigIntegerClass; +extern pVMClass arrayClass; +extern pVMClass methodClass; +extern pVMClass symbolClass; +extern pVMClass frameClass; +extern pVMClass primitiveClass; +extern pVMClass stringClass; +extern pVMClass systemClass; +extern pVMClass blockClass; +extern pVMClass doubleClass; + +using namespace std; +class Universe +{ +public: + + Universe* operator->(); + + //static methods + static Universe* GetUniverse(); + static void Start(int argc, char** argv); + static void Quit(int); + static void ErrorExit(const char*); + + //Globals accessor (only for GC, could be considered be + //declared as a private friend method for the GC) + map GetGlobals() {return globals;} + Heap* GetHeap() {return heap;} + Interpreter* GetInterpreter() {return interpreter;} + + // + + void Assert(bool) const; + + pVMSymbol SymbolFor(const StdString&); + pVMSymbol SymbolForChars(const char*); + + //VMObject instanciation methods. These should probably be refactored to a new class + pVMArray NewArray(int) const; + pVMArray NewArrayList(ExtendedList& list) const; + pVMArray NewArrayFromArgv(const vector&) const; + pVMBlock NewBlock(pVMMethod, pVMFrame, int); + pVMClass NewClass(pVMClass) const; + pVMFrame NewFrame(pVMFrame, pVMMethod) const; + pVMMethod NewMethod(pVMSymbol, size_t, size_t) const; + pVMObject NewInstance(pVMClass) const; + pVMInteger NewInteger(int32_t) const; + pVMBigInteger NewBigInteger(int64_t) const; + pVMDouble NewDouble(double) const; + pVMClass NewMetaclassClass(void) const; + pVMString NewString(const StdString&) const; + pVMSymbol NewSymbol(const StdString&); + pVMString NewString(const char*) const; + pVMSymbol NewSymbol(const char*); + pVMClass NewSystemClass(void) const; + + void InitializeSystemClass(pVMClass, pVMClass, const char*); + + pVMObject GetGlobal(pVMSymbol); + void SetGlobal(pVMSymbol name, pVMObject val); + bool HasGlobal(pVMSymbol); + void InitializeGlobals(); + pVMClass GetBlockClass(void) const; + pVMClass GetBlockClassWithArgs(int); + + pVMClass LoadClass(pVMSymbol); + void LoadSystemClass(pVMClass); + pVMClass LoadClassBasic(pVMSymbol, pVMClass); + pVMClass LoadShellClass(StdString&); + + Universe(); + ~Universe(); + // +private: + vector handleArguments(int argc, char** argv) ; + int getClassPathExt(vector& tokens, const StdString& arg) const; + + static Universe* theUniverse; + + int setupClassPath(const StdString& cp); + int addClassPath(const StdString& cp); + void printUsageAndExit(char* executable) const; + + + void initialize(int, char**); + + Heap* heap; + int heapSize; + map globals; + vector classPath; + + Symboltable* symboltable; + SourcecodeCompiler* compiler; + Interpreter* interpreter; +}; + + +#endif diff --git a/src/vmobjects/ObjectFormats.h b/src/vmobjects/ObjectFormats.h new file mode 100644 index 0000000..3ce1440 --- /dev/null +++ b/src/vmobjects/ObjectFormats.h @@ -0,0 +1,50 @@ +#pragma once +#ifndef OBJECTFORMATS_H_ +#define OBJECTFORMATS_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + +#define pVMArray VMPointer +#define pVMBigInteger VMPointer +#define pVMBlock VMPointer +#define pVMClass VMPointer +#define pVMDouble VMPointer +#define pVMEvaluationPrimitive VMPointer +#define pVMFrame VMPointer +#define pVMInteger VMPointer +#define pVMInvokable VMPointer +#define pVMMethod VMPointer +#define pVMObject VMPointer +#define pVMPrimitive VMPointer +#define pVMString VMPointer +#define pVMSymbol VMPointer + + + + + +#endif OBJECTFORMATS_H_ diff --git a/src/vmobjects/PrimitiveRoutine.h b/src/vmobjects/PrimitiveRoutine.h new file mode 100644 index 0000000..193c8bc --- /dev/null +++ b/src/vmobjects/PrimitiveRoutine.h @@ -0,0 +1,49 @@ +#pragma once +#ifndef PRIMITIVEROUTINE_H_ +#define PRIMITIVEROUTINE_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMObject.h" +#include "VMFrame.h" + +// abstract base class +class PrimitiveRoutine { +public: + PrimitiveRoutine() { }; + + virtual void operator()(pVMObject, pVMFrame)=0; // call using operator +}; + +// Typedefs for Primitive loading +typedef PrimitiveRoutine* CreatePrimitive(const std::string&,const std::string&); +typedef bool SupportsClass(const char*); +typedef void TearDown(); +typedef void Setup(); + +#endif diff --git a/src/vmobjects/Signature.cpp b/src/vmobjects/Signature.cpp new file mode 100644 index 0000000..3fb7445 --- /dev/null +++ b/src/vmobjects/Signature.cpp @@ -0,0 +1,75 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "Signature.h" +#include "VMSymbol.h" + + +int Signature::GetNumberOfArguments(pVMSymbol sig) { + // check default binaries + if(Signature::IsBinary(sig)) return 2; + else { + StdString str = sig->GetStdString(); + + // colons in str + int numColons =0; + + // search the str + for(unsigned int i=0 ; i<=str.length(); ++i) + if(str[i]==':') + // additional colon found + numColons++; + + // The number of arguments is equal to the number of colons plus one + // (->> SELF) + return numColons + 1; + } +} + + +bool Signature::IsBinary(pVMSymbol sig) { + StdString sigstr = sig->GetStdString(); + switch(sigstr[0]) { + case '~' : + case '&' : + case '|' : + case '*' : + case '/' : + case '@' : + case '+' : + case '-' : + case '=' : + case '>' : + case '<' : + case ',' : + case '%' : + case '\\': + return true; + default: break; + } + return false; +} diff --git a/src/vmobjects/Signature.h b/src/vmobjects/Signature.h new file mode 100644 index 0000000..b5c23c2 --- /dev/null +++ b/src/vmobjects/Signature.h @@ -0,0 +1,43 @@ +#pragma once +#ifndef SIGNATURE_H_ +#define SIGNATURE_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +class VMSymbol; +#include "../vmobjects/ObjectFormats.h" +#include "../vmobjects/VMPointer.h" + +class Signature { +public: + static int GetNumberOfArguments(pVMSymbol sig); + static bool IsBinary(pVMSymbol sig); + +}; + +#endif diff --git a/src/vmobjects/Symboltable.cpp b/src/vmobjects/Symboltable.cpp new file mode 100644 index 0000000..b24eb46 --- /dev/null +++ b/src/vmobjects/Symboltable.cpp @@ -0,0 +1,51 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "Symboltable.h" + + +pVMSymbol Symboltable::lookup(const char* restrict) { + return symtab[StdString(restrict)]; +} + + +pVMSymbol Symboltable::lookup(const StdString& restrict) { + return symtab[restrict]; +} + + +void Symboltable::insert(pVMSymbol sym) { + symtab[sym->GetStdString()] = sym; +} + + +Symboltable::Symboltable() { +} + + +Symboltable::~Symboltable() { +} diff --git a/src/vmobjects/Symboltable.h b/src/vmobjects/Symboltable.h new file mode 100644 index 0000000..8747d95 --- /dev/null +++ b/src/vmobjects/Symboltable.h @@ -0,0 +1,47 @@ +#pragma once +#ifndef SYMBOLTABLE_H_ +#define SYMBOLTABLE_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMSymbol.h" +#include "../misc/defs.h" + +class Symboltable { +public: + pVMSymbol lookup(const char* restrict); + pVMSymbol lookup(const StdString& restrict); + void insert(pVMSymbol); + + Symboltable(); + ~Symboltable(); +private: + map symtab; +}; + +#endif diff --git a/src/vmobjects/VMArray.cpp b/src/vmobjects/VMArray.cpp new file mode 100644 index 0000000..3dfc1e7 --- /dev/null +++ b/src/vmobjects/VMArray.cpp @@ -0,0 +1,87 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMArray.h" + +#include "../vm/Universe.h" + + +#define theEntries(i) FIELDS[this->GetNumberOfFields()+i] + +const int VMArray::VMArrayNumberOfFields = 0; + +VMArray::VMArray(int size, int nof) : VMObject(nof + VMArrayNumberOfFields) { + _HEAP->StartUninterruptableAllocation(); + + for (int i = 0; i < size ; ++i) { + (*this)[i] = nilObject; + } + _HEAP->EndUninterruptableAllocation(); + +} + + +pVMArray VMArray::CopyAndExtendWith(pVMObject item) const { + size_t fields = GetNumberOfIndexableFields(); + pVMArray result = _UNIVERSE->NewArray(fields+1); + this->CopyIndexableFieldsTo(result); + (*result)[fields] = item; + return result; +} + + +pVMObject& VMArray::operator[](int idx) const { + if (idx > GetNumberOfIndexableFields()-1 || idx < 0) { + cout << "Array index out of bounds: Accessing " << idx + << ", but array size is only " << GetNumberOfIndexableFields()-1 + << endl; + _UNIVERSE->ErrorExit("Array index out of bounds"); + } + return theEntries(idx); +} + + +void VMArray::CopyIndexableFieldsTo(pVMArray to) const { + for (int i = 0; i < this->GetNumberOfIndexableFields(); ++i) { + (*to)[i] = (*this)[i]; + } + +} + +int VMArray::GetNumberOfIndexableFields() const { + return this->GetAdditionalSpaceConsumption() / sizeof(pVMObject); +} + +void VMArray::MarkReferences() { + if (gcfield) return; + VMObject::MarkReferences(); + for (int i = 0 ; i < GetNumberOfIndexableFields() ; ++i) { + if (theEntries(i) != NULL) + theEntries(i)->MarkReferences(); + } + +} diff --git a/src/vmobjects/VMArray.h b/src/vmobjects/VMArray.h new file mode 100644 index 0000000..19a9fca --- /dev/null +++ b/src/vmobjects/VMArray.h @@ -0,0 +1,52 @@ +#pragma once +#ifndef VMARRAY_H_ +#define VMARRAY_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMObject.h" +#include "VMInteger.h" + +class VMArray : public VMObject { +public: + VMArray(int size, int nof = 0); + //virtual ~VMArray(); + virtual void MarkReferences(); + + virtual int GetNumberOfIndexableFields() const; + pVMArray CopyAndExtendWith(pVMObject) const; + void CopyIndexableFieldsTo(pVMArray) const; + + pVMObject& operator[](int idx) const; + +private: + static const int VMArrayNumberOfFields; +}; + + +#endif diff --git a/src/vmobjects/VMBigInteger.cpp b/src/vmobjects/VMBigInteger.cpp new file mode 100644 index 0000000..211c761 --- /dev/null +++ b/src/vmobjects/VMBigInteger.cpp @@ -0,0 +1,40 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMBigInteger.h" + +const int VMBigInteger::VMBigIntegerNumberOfFields = 0; + +VMBigInteger::VMBigInteger() : VMObject(VMBigIntegerNumberOfFields) { + this->embeddedInteger = 0; +} + + +VMBigInteger::VMBigInteger(int64_t val) : VMObject(VMBigIntegerNumberOfFields) { + this->embeddedInteger = val; +} + diff --git a/src/vmobjects/VMBigInteger.h b/src/vmobjects/VMBigInteger.h new file mode 100644 index 0000000..e73f3c0 --- /dev/null +++ b/src/vmobjects/VMBigInteger.h @@ -0,0 +1,59 @@ +#pragma once +#ifndef VMBIGINTEGER_H_ +#define VMBIGINTEGER_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "../misc/defs.h" + +#include "VMObject.h" + + +class VMBigInteger : public VMObject { +public: + VMBigInteger(); + VMBigInteger(int64_t); + + inline void SetEmbeddedInteger(int64_t); + inline int64_t GetEmbeddedInteger() const; + +private: + int64_t embeddedInteger; + + static const int VMBigIntegerNumberOfFields; +}; + +int64_t VMBigInteger::GetEmbeddedInteger() const { + return this->embeddedInteger; +} + + +void VMBigInteger::SetEmbeddedInteger(int64_t val) { + this->embeddedInteger = val; +} +#endif diff --git a/src/vmobjects/VMBlock.cpp b/src/vmobjects/VMBlock.cpp new file mode 100644 index 0000000..a292a28 --- /dev/null +++ b/src/vmobjects/VMBlock.cpp @@ -0,0 +1,60 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMBlock.h" +#include "VMMethod.h" +#include "VMFrame.h" +#include "VMEvaluationPrimitive.h" + +#include "../vm/Universe.h" + +const int VMBlock::VMBlockNumberOfFields = 2; + +VMBlock::VMBlock() : VMObject(VMBlockNumberOfFields), +blockMethod(nilObject), context(nilObject) { +} + +void VMBlock::SetMethod(pVMMethod bMethod) { + blockMethod = (bMethod); +} + + +pVMMethod VMBlock::GetMethod() const { + return (blockMethod); +} + + +void VMBlock::MarkReferences() { + if (gcfield) return; + VMObject::MarkReferences(); +} + + + +pVMEvaluationPrimitive VMBlock::GetEvaluationPrimitive(int numberOfArguments) { + return new (_HEAP) VMEvaluationPrimitive(numberOfArguments); +} diff --git a/src/vmobjects/VMBlock.h b/src/vmobjects/VMBlock.h new file mode 100644 index 0000000..acc9348 --- /dev/null +++ b/src/vmobjects/VMBlock.h @@ -0,0 +1,69 @@ +#pragma once +#ifndef VMBLOCK_H_ +#define VMBLOCK_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMObject.h" + +class VMMethod; +class VMFrame; +class VMEvaluationPrimitive; + +class VMBlock : public VMObject { +public: + VMBlock(); + //virtual ~VMBlock(); + virtual void MarkReferences(); + + void SetMethod(pVMMethod); + pVMMethod GetMethod() const; + inline void SetContext(pVMFrame); + inline pVMFrame GetContext() const; + + static pVMEvaluationPrimitive GetEvaluationPrimitive(int); +private: + pVMMethod blockMethod; + pVMFrame context; + + static const int VMBlockNumberOfFields; +}; + + + + +void VMBlock::SetContext(pVMFrame contxt) { + context = contxt; +} + + +pVMFrame VMBlock::GetContext() const { + return context; +} + +#endif diff --git a/src/vmobjects/VMClass.cpp b/src/vmobjects/VMClass.cpp new file mode 100644 index 0000000..e9ba62c --- /dev/null +++ b/src/vmobjects/VMClass.cpp @@ -0,0 +1,417 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + +#include "VMClass.h" +#include "VMArray.h" +#include "VMSymbol.h" +#include "VMInvokable.h" +#include "VMPrimitive.h" +#include "PrimitiveRoutine.h" +#include "VMPointerConverter.h" + +#include +#include + +#if defined(__GNUC__) +# include +#else //Visual Studio +/** + * Emualting the dl-interface with win32 means + */ +# define WIN32_LEAN_AND_MEAN +# define dlerror() "Load Error" +# define dlsym GetProcAddress +# define DL_LOADMODE NULL, LOAD_WITH_ALTERED_SEARCH_PATH +# define dlopen LoadLibrary +# define dlclose FreeLibrary +//# include //included in VMClass.h if necessary + +#endif + + +/* + * Format definitions for Primitive naming scheme. + * + */ +#define CLASS_METHOD_FORMAT_S "%s::%s" +// as in AClass::aClassMethod +#define INSTANCE_METHOD_FORMAT_S "%s::%s_" +// as in AClass::anInstanceMethod_ + + +const int VMClass::VMClassNumberOfFields = 4; + +VMClass::VMClass() : VMObject(VMClassNumberOfFields), +superClass(nilObject), name(nilObject), instanceFields(nilObject), instanceInvokables(nilObject) { +} + + +VMClass::VMClass( int numberOfFields ) : VMObject(numberOfFields + VMClassNumberOfFields), +superClass(nilObject), name(nilObject), instanceFields(nilObject), instanceInvokables(nilObject) { +} + + +bool VMClass::HasSuperClass() const { + return (superClass != NULL && superClass != nilObject); +} + + +bool VMClass::AddInstanceInvokable(pVMObject ptr) { + pVMInvokable newInvokable = DynamicConvert(ptr); + if (newInvokable == NULL) { + _UNIVERSE->ErrorExit("Error: trying to add non-invokable to invokables array"); + } + //Check whether an invokable with the same signature exists and replace it if that's the case + for (int i = 0; i < instanceInvokables->GetNumberOfIndexableFields(); ++i) { + pVMInvokable inv = DynamicConvert( (*instanceInvokables)[i] ); + if (inv != NULL) { + if (newInvokable->GetSignature() == inv->GetSignature()) { + this->SetInstanceInvokable(i, ptr); + return false; + } + + } else { + _UNIVERSE->ErrorExit("Invokables array corrupted. Either NULL pointer added or pointer to non-invokable."); + } + } + //it's a new invokable so we need to expand the invokables array. + instanceInvokables = instanceInvokables->CopyAndExtendWith(ptr); + + return true; +} + + +void VMClass::AddInstancePrimitive(pVMPrimitive ptr) { + if (AddInstanceInvokable((pVMObject)ptr)) { + //cout << "Warn: Primitive "<GetSignature<<" is not in class definition for class " << name->GetStdString() << endl; + } +} + + +pVMSymbol VMClass::GetInstanceFieldName(int index) const { + if (index >= numberOfSuperInstanceFields()) { + index -= numberOfSuperInstanceFields(); + return (pVMSymbol) (*instanceFields)[index]; + } + + return superClass->GetInstanceFieldName(index); +} + + + + +void VMClass::SetInstanceInvokables(pVMArray invokables) { + + instanceInvokables = invokables; + + for (int i = 0; i < this->GetNumberOfInstanceInvokables(); ++i) { + pVMObject invo = (*instanceInvokables)[i]; + //check for Nil object + if (invo != nilObject) { + //not Nil, so this actually is an invokable + pVMInvokable inv = DynamicConvert(invo); + inv->SetHolder(this); + } + } + +} + + +int VMClass::GetNumberOfInstanceInvokables() const { + return instanceInvokables->GetNumberOfIndexableFields(); +} + + +pVMObject VMClass::GetInstanceInvokable(int index) const { + return (*instanceInvokables)[index]; +} + + +void VMClass::SetInstanceInvokable(int index, pVMObject invokable) { + (*instanceInvokables)[index] = invokable; + if (invokable != nilObject) { + pVMInvokable inv = DynamicConvert( invokable ); + inv->SetHolder(this); + } +} + + +pVMObject VMClass::LookupInvokable(pVMSymbol name) const { + pVMInvokable invokable = NULL; + for (int i = 0; i < GetNumberOfInstanceInvokables(); ++i) { + invokable = (pVMInvokable)(GetInstanceInvokable(i)); + if (invokable->GetSignature() == name) + return (pVMObject)(invokable); + } + invokable = NULL; + //look in super class + if (this->HasSuperClass()) { + invokable = (pVMInvokable)(this->superClass->LookupInvokable(name)); + } + return (pVMObject)(invokable); +} + + +int VMClass::LookupFieldIndex(pVMSymbol name) const { + for (int i = 0; i <=GetNumberOfInstanceFields(); ++i) { + //even with GetNumberOfInstanceFields == 0 there is the class field + if (name == this->GetInstanceFieldName(i) || + name->GetStdString() == this->GetInstanceFieldName(i)->GetStdString()) + return i; + } + return -1; +} + + +int VMClass::GetNumberOfInstanceFields() const { + return instanceFields->GetNumberOfIndexableFields() + + this->numberOfSuperInstanceFields(); +} + + +bool VMClass::HasPrimitives() const { + for (int i = 0; i < GetNumberOfInstanceInvokables(); ++i) { + pVMInvokable invokable = (pVMInvokable)(GetInstanceInvokable(i)); + if (invokable->IsPrimitive()) return true; + } + return false; +} + + +void VMClass::LoadPrimitives(const vector& cp) { + + // the library handle + void* dlhandle=NULL; + // + // cached object properties + StdString cname = this->name->GetStdString(); + +#if defined (__GNUC__) + //// iterate the classpathes + for(vector::const_iterator i = cp.begin(); (i != cp.end()) && dlhandle == NULL; ++i) { + // check the core library + StdString loadstring = genCoreLoadstring(*i); + dlhandle = loadLib(loadstring); + if(dlhandle != NULL) { + + if(isResponsible(dlhandle, cname)) + // the core library is found and responsible + break; + } + + // the core library is not found or not responsible, + // continue w/ class file + loadstring = genLoadstring(*i, cname); + cout << loadstring.c_str() << endl; + dlhandle = loadLib(loadstring); + if(dlhandle != NULL) { + // + // the class library was found... + // + if(isResponsible(dlhandle, cname)) { + // + // ...and is responsible. + // + break; + } else { + // + // ... but says not responsible, but we have to + // close it nevertheless + // + dlclose(dlhandle); + _UNIVERSE->ErrorExit("Library claims no resonsibility, but musn't!"); + } + + } + /* + * continue checking the next class path + */ + } + + // finished cycling, + // check if a lib was found. + if(dlhandle == NULL) { + cout << "load failure: "; + cout << "could not load primitive library for " << cname << endl; + _UNIVERSE->Quit(ERR_FAIL); + } + +#endif + ///* + // * do the actual loading for both class and metaclass + // * + // */ + setPrimitives(dlhandle, cname); + GetClass()->setPrimitives(dlhandle, cname); +} + +int VMClass::numberOfSuperInstanceFields() const { + if (this->HasSuperClass()) + return this->superClass->GetNumberOfInstanceFields(); + return 0; +} + +//LoadPrimitives helper +#define sharedExtension ".csp" + +StdString VMClass::genLoadstring(const StdString& cp, + const StdString& cname + ) const { + + StdString loadstring = string(cp); + loadstring += fileSeparator; + loadstring += cname; + loadstring += sharedExtension; + + return loadstring; +} + + +/** + * generate the string containing the path to a SOMCore which may be located + * at the classpath given. + * + */ +StdString VMClass::genCoreLoadstring(const StdString& cp) const { + #define S_CORE "SOMCore" + StdString corename = string(S_CORE); + StdString result = genLoadstring(cp, corename); + + return result; +} + + +/** + * load the given library, return the handle + * + */ +void* VMClass::loadLib(const StdString& path) const { +#ifdef __DEBUG + cout << "loadLib " << path << endl; +#endif +#if defined(__GNUC__) + #ifdef DEBUG + #define DL_LOADMODE RTLD_NOW + #else + #define DL_LOADMODE RTLD_LAZY + #endif + + + // static handle. will be returned + void* dlhandle; + // try load lib + if((dlhandle=dlopen(path.c_str(), DL_LOADMODE))) { + //found. + return dlhandle; + } else { + cout << "Error loading library "<ErrorExit("Library doesn't have expected format: "); + } + + // test class responsibility + return supports_class(cl.c_str()); +#else + return true; +#endif +} + + + + +/* + * set the routines for primitive marked invokables of the given class + * + */ +void VMClass::setPrimitives(void* dlhandle, const StdString& cname) { + pVMPrimitive thePrimitive; + PrimitiveRoutine* routine=NULL; + pVMInvokable anInvokable; + // iterate invokables + for(int i = 0; i < this->GetNumberOfInstanceInvokables(); i++) { + + anInvokable = (pVMInvokable)(this->GetInstanceInvokable(i)); +#ifdef __DEBUG + cout << "cname: >" << cname << "<"<< endl; + cout << an_invokable->GetSignature()->GetStdString() << endl; +#endif + if(anInvokable->IsPrimitive()) { +#ifdef __DEBUG + cout << "... is a primitive, and is going to be loaded now" << endl; +#endif + thePrimitive = (pVMPrimitive)( anInvokable ); + // + // we have a primitive to load + // get it's selector + // + pVMSymbol sig = thePrimitive->GetSignature(); + StdString selector = sig->GetPlainString(); +#if defined(__GNUC__) + CreatePrimitive* create = + (CreatePrimitive*) dlsym(dlhandle, "create"); +#endif + routine = create(cname, selector); + + if(!routine) { + cout << "could not load primitive '"<< selector + <<"' for class " << cname << endl; + + _UNIVERSE->Quit(ERR_FAIL); + } + + + // set routine + thePrimitive->SetRoutine(routine); + thePrimitive->SetEmpty(false); + } +#ifdef __DEBUG + else { + cout << "... is not a primitive" << endl; + } +#endif + } +} + diff --git a/src/vmobjects/VMClass.h b/src/vmobjects/VMClass.h new file mode 100644 index 0000000..3c8acc4 --- /dev/null +++ b/src/vmobjects/VMClass.h @@ -0,0 +1,135 @@ +#pragma once +#ifndef VMCLASS_H_ +#define VMCLASS_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include + +#include "VMObject.h" + +#include "../misc/defs.h" + + +#if defined(_MSC_VER) //Visual Studio + #include + #include "../primitives/Core.h" +#endif + +class VMSymbol; +class VMArray; +class VMPrimitive; +class ClassGenerationContext; + +class VMClass : public VMObject { +public: + VMClass(); + VMClass(int numberOfFields); + + virtual inline pVMClass GetSuperClass() const; + virtual inline void SetSuperClass(pVMClass); + virtual bool HasSuperClass() const; + virtual inline pVMSymbol GetName() const; + virtual inline void SetName(pVMSymbol); + virtual inline pVMArray GetInstanceFields() const; + virtual inline void SetInstanceFields(pVMArray); + virtual inline pVMArray GetInstanceInvokables() const; + virtual void SetInstanceInvokables(pVMArray); + virtual int GetNumberOfInstanceInvokables() const; + virtual pVMObject GetInstanceInvokable(int) const; + virtual void SetInstanceInvokable(int, pVMObject); + virtual pVMObject LookupInvokable(pVMSymbol) const; + virtual int LookupFieldIndex(pVMSymbol) const; + virtual bool AddInstanceInvokable(pVMObject); + virtual void AddInstancePrimitive(pVMPrimitive); + virtual pVMSymbol GetInstanceFieldName(int)const; + virtual int GetNumberOfInstanceFields() const; + virtual bool HasPrimitives() const; + virtual void LoadPrimitives(const vector&); + + +private: + + + StdString genLoadstring(const StdString& cp, + const StdString& cname + ) const; + + StdString genCoreLoadstring(const StdString& cp) const; + + void* loadLib(const StdString& path) const; + bool isResponsible(void* handle, const StdString& cl) const; + void setPrimitives(void* handle, const StdString& cname); + + + int numberOfSuperInstanceFields() const; + + pVMClass superClass; + pVMSymbol name; + pVMArray instanceFields; + pVMArray instanceInvokables; + + static const int VMClassNumberOfFields; +}; + + +pVMClass VMClass::GetSuperClass() const { + return superClass; +} + + +void VMClass::SetSuperClass(pVMClass sup) { + superClass = sup; +} + + +pVMSymbol VMClass::GetName() const { + return name; +} + + +void VMClass::SetName(pVMSymbol nam) { + name = nam; +} + + +pVMArray VMClass::GetInstanceFields() const { + return instanceFields; +} + + +void VMClass::SetInstanceFields(pVMArray instFields) { + instanceFields = instFields; +} + + +pVMArray VMClass::GetInstanceInvokables() const { + return instanceInvokables; +} + +#endif diff --git a/src/vmobjects/VMDouble.cpp b/src/vmobjects/VMDouble.cpp new file mode 100644 index 0000000..d867369 --- /dev/null +++ b/src/vmobjects/VMDouble.cpp @@ -0,0 +1,42 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMDouble.h" + +const int VMDouble::VMDoubleNumberOfFields = 0; + +VMDouble::VMDouble() : VMObject(VMDoubleNumberOfFields) { + this->embeddedDouble = 0.0f; +} + + +VMDouble::VMDouble(double val) : VMObject(VMDoubleNumberOfFields) { + this->embeddedDouble = val; +} + + + diff --git a/src/vmobjects/VMDouble.h b/src/vmobjects/VMDouble.h new file mode 100644 index 0000000..b16b84e --- /dev/null +++ b/src/vmobjects/VMDouble.h @@ -0,0 +1,57 @@ +#pragma once +#ifndef VMDOUBLE_H_ +#define VMDOUBLE_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMObject.h" + + +class VMDouble : public VMObject { +public: + VMDouble(); + VMDouble(double); + + inline void SetEmbeddedDouble(double); + inline double GetEmbeddedDouble() const; +private: + double embeddedDouble; + + static const int VMDoubleNumberOfFields; +}; + +void VMDouble::SetEmbeddedDouble(double val) { + this->embeddedDouble = val; +} + + +double VMDouble::GetEmbeddedDouble() const { + return this->embeddedDouble; +} + +#endif diff --git a/src/vmobjects/VMEvaluationPrimitive.cpp b/src/vmobjects/VMEvaluationPrimitive.cpp new file mode 100644 index 0000000..bc1d9a4 --- /dev/null +++ b/src/vmobjects/VMEvaluationPrimitive.cpp @@ -0,0 +1,99 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMEvaluationPrimitive.h" +#include "VMSymbol.h" +#include "VMObject.h" +#include "VMFrame.h" +#include "VMBlock.h" +#include "VMInteger.h" + +#include "../vm/Universe.h" + +//needed to instanciate the Routine object for the evaluation routine +#include "../primitivesCore/Routine.h" + + +VMEvaluationPrimitive::VMEvaluationPrimitive(int argc) : + VMPrimitive(computeSignatureString(argc)) { + _HEAP->StartUninterruptableAllocation(); + this->SetRoutine(new Routine(this, + &VMEvaluationPrimitive::evaluationRoutine)); + this->SetEmpty(false); + this->numberOfArguments = _UNIVERSE->NewInteger(argc); + _HEAP->EndUninterruptableAllocation(); +} + + +void VMEvaluationPrimitive::MarkReferences() { + VMPrimitive::MarkReferences(); + this->numberOfArguments->MarkReferences(); +} + + + +pVMSymbol VMEvaluationPrimitive::computeSignatureString(int argc){ +#define VALUE_S "value" +#define VALUE_LEN 5 +#define WITH_S "with:" +#define WITH_LEN (4+1) +#define COLON_S ":" + + StdString signatureString; + + // Compute the signature string + if(argc==1) { + signatureString += VALUE_S; + } else { + signatureString += VALUE_S ; + signatureString += COLON_S; + --argc; + while(--argc) + // Add extra value: selector elements if necessary + signatureString + WITH_S; + } + + // Return the signature string + return _UNIVERSE->SymbolFor(signatureString); +} + +void VMEvaluationPrimitive::evaluationRoutine(pVMObject object, pVMFrame frame){ + pVMEvaluationPrimitive self = (pVMEvaluationPrimitive) object; + + // Get the block (the receiver) from the stack + int numArgs = self->numberOfArguments->GetEmbeddedInteger(); + pVMBlock block = (pVMBlock) frame->GetStackElement(numArgs - 1); + + // Get the context of the block... + pVMFrame context = block->GetContext(); + + // Push a new frame and set its context to be the one specified in the block + pVMFrame NewFrame = _UNIVERSE->GetInterpreter()->PushNewFrame( + block->GetMethod()); + NewFrame->CopyArgumentsFrom(frame); + NewFrame->SetContext(context); +} diff --git a/src/vmobjects/VMEvaluationPrimitive.h b/src/vmobjects/VMEvaluationPrimitive.h new file mode 100644 index 0000000..b7b29f5 --- /dev/null +++ b/src/vmobjects/VMEvaluationPrimitive.h @@ -0,0 +1,50 @@ +#pragma once +#ifndef VMEVALUATIONPRIMITIVE_H_ +#define VMEVALUATIONPRIMITIVE_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMPrimitive.h" +class VMInteger; +class VMObject; +class VMFrame; + + +class VMEvaluationPrimitive : public VMPrimitive { +public: + VMEvaluationPrimitive(int argc); + + virtual void MarkReferences(); +private: + static pVMSymbol computeSignatureString(int argc); + void evaluationRoutine(pVMObject object, pVMFrame frame); + pVMInteger numberOfArguments; + +}; + +#endif diff --git a/src/vmobjects/VMFrame.cpp b/src/vmobjects/VMFrame.cpp new file mode 100644 index 0000000..e3eb095 --- /dev/null +++ b/src/vmobjects/VMFrame.cpp @@ -0,0 +1,242 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMFrame.h" +#include "VMMethod.h" +#include "VMObject.h" +#include "VMInteger.h" +#include "VMClass.h" +#include "VMSymbol.h" + +#include "../vm/Universe.h" + +//when doesNotUnderstand or UnknownGlobal is sent, additional stack slots might +//be necessary, as these cases are not taken into account when the stack +//depth is calculated. In that case this method is called. +pVMFrame VMFrame::EmergencyFrameFrom( pVMFrame from, int extraLength ) { + int length = from->GetNumberOfIndexableFields() + extraLength; + int additionalBytes = length * sizeof(pVMObject); + pVMFrame result = new (_HEAP, additionalBytes) VMFrame(length); + + result->SetClass(from->GetClass()); + //copy arguments, locals and the stack + from->CopyIndexableFieldsTo(result); + + //set Frame members + result->SetPreviousFrame(from->GetPreviousFrame()); + result->SetMethod(from->GetMethod()); + result->SetContext(from->GetContext()); + result->stackPointer = from->GetStackPointer(); + result->bytecodeIndex = from->bytecodeIndex; + result->localOffset = from->localOffset; + + return result; +} + + +const int VMFrame::VMFrameNumberOfFields = 6; + +VMFrame::VMFrame(int size, int nof) : VMArray(size, nof + VMFrameNumberOfFields), + previousFrame(nilObject), context(nilObject), method(nilObject) { + _HEAP->StartUninterruptableAllocation(); + this->localOffset = _UNIVERSE->NewInteger(0); + this->bytecodeIndex = _UNIVERSE->NewInteger(0); + this->stackPointer = _UNIVERSE->NewInteger(0); + _HEAP->EndUninterruptableAllocation(); +} + +pVMMethod VMFrame::GetMethod() const { + + return this->method; +} + +void VMFrame::SetMethod(pVMMethod method) { + this->method = method; +} + +bool VMFrame::HasPreviousFrame() const { + return this->previousFrame != nilObject; +} + + + + +bool VMFrame::HasContext() const { + return this->context != nilObject; +} + + +pVMFrame VMFrame::GetContextLevel(int lvl) { + pVMFrame current = this; + while (lvl > 0) { + current = current->GetContext(); + --lvl; + } + return current; +} + + +pVMFrame VMFrame::GetOuterContext() { + pVMFrame current = this; + while (current->HasContext()) { + current = current->GetContext(); + } + return current; +} + + + +int VMFrame::RemainingStackSize() const { + // - 1 because the stack pointer points at the top entry, + // so the next entry would be put at stackPointer+1 + return this->GetNumberOfIndexableFields() - + stackPointer->GetEmbeddedInteger() - 1; +} + +pVMObject VMFrame::Pop() { + int32_t sp = this->stackPointer->GetEmbeddedInteger(); + this->stackPointer->SetEmbeddedInteger(sp-1); + return (*this)[sp]; +} + + +void VMFrame::Push(pVMObject obj) { + int32_t sp = this->stackPointer->GetEmbeddedInteger() + 1; + this->stackPointer->SetEmbeddedInteger(sp); + (*this)[sp] = obj; +} + + +void VMFrame::PrintStack() const { + cout << "SP: " << this->stackPointer->GetEmbeddedInteger() << endl; + for (int i = 0; i < this->GetNumberOfIndexableFields()+1; ++i) { + pVMObject vmo = (*this)[i]; + cout << i << ": "; + if (vmo == NULL) + cout << "NULL" << endl; + if (vmo == nilObject) + cout << "NIL_OBJECT" << endl; + if (vmo->GetClass() == NULL) + cout << "VMObject with Class == NULL" << endl; + if (vmo->GetClass() == nilObject) + cout << "VMObject with Class == NIL_OBJECT" << endl; + else + cout << "index: " << i << " object:" + << vmo->GetClass()->GetName()->GetChars() << endl; + } +} + + +void VMFrame::ResetStackPointer() { + // arguments are stored in front of local variables + pVMMethod meth = this->GetMethod(); + size_t lo = meth->GetNumberOfArguments(); + this->localOffset->SetEmbeddedInteger(lo); + + // Set the stack pointer to its initial value thereby clearing the stack + size_t numLocals = meth->GetNumberOfLocals(); + this->stackPointer->SetEmbeddedInteger(lo + numLocals - 1); +} + + +int VMFrame::GetBytecodeIndex() const { + return this->bytecodeIndex->GetEmbeddedInteger(); +} + + +void VMFrame::SetBytecodeIndex(int index) { + this->bytecodeIndex->SetEmbeddedInteger(index); +} + + +pVMObject VMFrame::GetStackElement(int index) const { + int sp = this->stackPointer->GetEmbeddedInteger(); + return (*this)[sp-index]; +} + + +void VMFrame::SetStackElement(int index, pVMObject obj) { + int sp = this->stackPointer->GetEmbeddedInteger(); + (*this)[sp-index] = obj; +} + + +pVMObject VMFrame::GetLocal(int index, int contextLevel) { + pVMFrame context = this->GetContextLevel(contextLevel); + int32_t lo = context->localOffset->GetEmbeddedInteger(); + return (*context)[lo+index]; +} + + +void VMFrame::SetLocal(int index, int contextLevel, pVMObject value) { + pVMFrame context = this->GetContextLevel(contextLevel); + size_t lo = context->localOffset->GetEmbeddedInteger(); + (*context)[lo+index] = value; +} + + + +pVMObject VMFrame::GetArgument(int index, int contextLevel) { + // get the context + pVMFrame context = this->GetContextLevel(contextLevel); + return (*context)[index]; +} + + +void VMFrame::SetArgument(int index, int contextLevel, pVMObject value) { + pVMFrame context = this->GetContextLevel(contextLevel); + (*context)[index] = value; +} + + +void VMFrame::PrintStackTrace() const { + //TODO +} + +int VMFrame::ArgumentStackIndex(int index) const { + pVMMethod meth = this->GetMethod(); + return meth->GetNumberOfArguments() - index - 1; +} + + +void VMFrame::CopyArgumentsFrom(pVMFrame frame) { + // copy arguments from frame: + // - arguments are at the top of the stack of frame. + // - copy them into the argument area of the current frame + pVMMethod meth = this->GetMethod(); + int num_args = meth->GetNumberOfArguments(); + for(int i=0; i < num_args; ++i) { + pVMObject stackElem = frame->GetStackElement(num_args - 1 - i); + (*this)[i] = stackElem; + } +} + + +void VMFrame::MarkReferences() { + if (gcfield) return; + VMArray::MarkReferences(); +} diff --git a/src/vmobjects/VMFrame.h b/src/vmobjects/VMFrame.h new file mode 100644 index 0000000..f8d1087 --- /dev/null +++ b/src/vmobjects/VMFrame.h @@ -0,0 +1,119 @@ +#pragma once +#ifndef VMFRAME_H_ +#define VMFRAME_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + + +#include "VMArray.h" +class VMMethod; +class VMObject; +class VMInteger; + + +class VMFrame : public VMArray { +public: + static pVMFrame EmergencyFrameFrom(pVMFrame from, int extraLength); + + VMFrame(int size, int nof = 0); + + virtual inline pVMFrame GetPreviousFrame() const; + virtual inline void SetPreviousFrame(pVMObject); + virtual inline void ClearPreviousFrame(); + virtual bool HasPreviousFrame() const; + virtual inline bool IsBootstrapFrame() const; + virtual inline pVMFrame GetContext() const; + virtual inline void SetContext(pVMFrame); + virtual bool HasContext() const; + virtual pVMFrame GetContextLevel(int); + virtual pVMFrame GetOuterContext(); + virtual pVMMethod GetMethod() const; + virtual void SetMethod(pVMMethod); + virtual pVMObject Pop(); + virtual void Push(pVMObject); + virtual void ResetStackPointer(); + virtual int GetBytecodeIndex() const; + virtual void SetBytecodeIndex(int); + virtual pVMObject GetStackElement(int) const; + virtual void SetStackElement(int, pVMObject); + virtual pVMObject GetLocal(int, int); + virtual void SetLocal(int, int, pVMObject); + virtual pVMObject GetArgument(int, int); + virtual void SetArgument(int, int, pVMObject); + virtual void PrintStackTrace() const; + virtual int ArgumentStackIndex(int index) const; + virtual void CopyArgumentsFrom(pVMFrame frame); + + virtual void MarkReferences(); + virtual void PrintStack() const; + virtual inline pVMInteger GetStackPointer() const; + virtual int RemainingStackSize() const; +private: + pVMFrame previousFrame; + pVMFrame context; + pVMMethod method; + pVMInteger stackPointer; + pVMInteger bytecodeIndex; + pVMInteger localOffset; + + static const int VMFrameNumberOfFields; +}; + +bool VMFrame::IsBootstrapFrame() const { + return !HasPreviousFrame(); +} + +pVMFrame VMFrame::GetContext() const { + return this->context; +} + +void VMFrame::SetContext(pVMFrame frm) { + this->context = frm; +} + +pVMInteger VMFrame::GetStackPointer() const { + return stackPointer; +} + + + +pVMFrame VMFrame::GetPreviousFrame() const { + return (pVMFrame) this->previousFrame; +} + + +void VMFrame::SetPreviousFrame(pVMObject frm) { + this->previousFrame = (pVMFrame)frm; +} + +void VMFrame::ClearPreviousFrame() { + this->previousFrame = (pVMFrame)nilObject; +} + + +#endif diff --git a/src/vmobjects/VMFreeObject.cpp b/src/vmobjects/VMFreeObject.cpp new file mode 100644 index 0000000..cc10464 --- /dev/null +++ b/src/vmobjects/VMFreeObject.cpp @@ -0,0 +1,51 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMFreeObject.h" + + +VMFreeObject::VMFreeObject() : VMObject(0) { + this->gcfield = -1; +} + +void VMFreeObject::SetNext(VMFreeObject* next) { + this->hash = (int32_t) next; +} + +VMFreeObject* VMFreeObject::GetNext() { + return (VMFreeObject*)this->hash; +} + +void VMFreeObject::SetPrevious(VMFreeObject* prev) { + this->numberOfFields = (int32_t)prev; +} + +VMFreeObject* VMFreeObject::GetPrevious() { + return (VMFreeObject*)this->numberOfFields; +} + + diff --git a/src/vmobjects/VMFreeObject.h b/src/vmobjects/VMFreeObject.h new file mode 100644 index 0000000..8910f24 --- /dev/null +++ b/src/vmobjects/VMFreeObject.h @@ -0,0 +1,55 @@ +#pragma once +#ifndef VMFREEOBJECT_H_ +#define VMFREEOBJECT_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMObject.h" + +//This class represents unused memory in the heap. +//Its objectSize field states the size of the unused memory chunk. +//In order to build a double linked list of free memory chunks in the +//heap, some fields are used outside their normal purpose: +//The hash field is ("ab"-)used as the "next" pointer in the free-list. +//The numberOfFields field is ("ab"-)used as the "previous" pointer in +//the double-linked free-list. +//Unused objects are marked as -1 in the gc_field; +class VMFreeObject : public VMObject { +public: + VMFreeObject(); + + void SetNext(VMFreeObject* next); + VMFreeObject* GetNext(); + void SetPrevious(VMFreeObject* prev); + VMFreeObject* GetPrevious(); +}; + + +#endif + + diff --git a/src/vmobjects/VMInteger.cpp b/src/vmobjects/VMInteger.cpp new file mode 100644 index 0000000..b6ee081 --- /dev/null +++ b/src/vmobjects/VMInteger.cpp @@ -0,0 +1,43 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMInteger.h" + +const int VMInteger::VMIntegerNumberOfFields = 0; + +VMInteger::VMInteger() : VMObject(VMIntegerNumberOfFields) { + embeddedInteger = 0; +} + + +VMInteger::VMInteger(int32_t val) : VMObject(VMIntegerNumberOfFields) { + embeddedInteger = val; +} + + + + diff --git a/src/vmobjects/VMInteger.h b/src/vmobjects/VMInteger.h new file mode 100644 index 0000000..564231b --- /dev/null +++ b/src/vmobjects/VMInteger.h @@ -0,0 +1,59 @@ +#pragma once +#ifndef VMINTEGER_H_ +#define VMINTEGER_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMObject.h" + +#include "../misc/defs.h" + + +class VMInteger : public VMObject { +public: + VMInteger(); + VMInteger(int32_t); + + inline void SetEmbeddedInteger(int32_t); + inline int32_t GetEmbeddedInteger() const; +private: + int32_t embeddedInteger; + + static const int VMIntegerNumberOfFields; +}; + +void VMInteger::SetEmbeddedInteger(int32_t val) { + this->embeddedInteger = val; +} + + +int32_t VMInteger::GetEmbeddedInteger() const { + return this->embeddedInteger; +} + +#endif diff --git a/src/vmobjects/VMInvokable.cpp b/src/vmobjects/VMInvokable.cpp new file mode 100644 index 0000000..1dcd2e6 --- /dev/null +++ b/src/vmobjects/VMInvokable.cpp @@ -0,0 +1,58 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMInvokable.h" +#include "VMSymbol.h" +#include "VMClass.h" + +VMInvokable::VMInvokable(int nof) : VMObject(nof + 2), + signature(nilObject), holder(nilObject) { +} + +bool VMInvokable::IsPrimitive() const { + return false; +} + + +pVMSymbol VMInvokable::GetSignature() const { + return signature; +} + + +void VMInvokable::SetSignature(pVMSymbol sig) { + signature = sig; +} + + +pVMClass VMInvokable::GetHolder() const { + return holder; +} + + +void VMInvokable::SetHolder(pVMClass hld) { + holder = hld; +} diff --git a/src/vmobjects/VMInvokable.h b/src/vmobjects/VMInvokable.h new file mode 100644 index 0000000..49e1816 --- /dev/null +++ b/src/vmobjects/VMInvokable.h @@ -0,0 +1,56 @@ +#pragma once +#ifndef VMINVOKABLE_H_ +#define VMINVOKABLE_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "ObjectFormats.h" +#include "VMObject.h" +class VMSymbol; +class VMClass; +class VMFrame; + +class VMInvokable : public VMObject { +public: + VMInvokable(int nof = 0); + //virtual operator "()" to invoke the invokable + virtual void operator()(pVMFrame) = 0; + + virtual bool IsPrimitive() const; + virtual pVMSymbol GetSignature() const; + virtual void SetSignature(pVMSymbol sig); + virtual pVMClass GetHolder() const; + virtual void SetHolder(pVMClass hld); + +protected: + pVMSymbol signature; + pVMClass holder; +}; + + +#endif diff --git a/src/vmobjects/VMMethod.cpp b/src/vmobjects/VMMethod.cpp new file mode 100644 index 0000000..072b71c --- /dev/null +++ b/src/vmobjects/VMMethod.cpp @@ -0,0 +1,199 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMMethod.h" +#include "VMFrame.h" +#include "VMClass.h" +#include "VMSymbol.h" +#include "VMArray.h" +#include "VMObject.h" +#include "VMInteger.h" +#include "Signature.h" +#include "VMPointerConverter.h" + +#include "../vm/Universe.h" + +#include "../compiler/MethodGenerationContext.h" + +//this method's bytecodes +#define _BC ((uint8_t*)&FIELDS[this->GetNumberOfFields() + this->GetNumberOfIndexableFields()]) + +//this method's literals (-> VMArray) +#define theEntries(i) FIELDS[this->GetNumberOfFields()+i] + +const int VMMethod::VMMethodNumberOfFields = 5; + +VMMethod::VMMethod(int bcCount, int numberOfConstants, int nof) + : VMInvokable(nof + VMMethodNumberOfFields) { + _HEAP->StartUninterruptableAllocation(); + bcLength = _UNIVERSE->NewInteger( bcCount ); + numberOfLocals = _UNIVERSE->NewInteger(0); + maximumNumberOfStackElements = _UNIVERSE->NewInteger(0); + numberOfArguments = _UNIVERSE->NewInteger(0); + this->numberOfConstants = _UNIVERSE->NewInteger(numberOfConstants); + for (int i = 0; i < numberOfConstants ; ++i) { + this->SetIndexableField(i, nilObject); + } + _HEAP->EndUninterruptableAllocation(); +} + +void VMMethod::SetSignature(pVMSymbol sig) { + VMInvokable::SetSignature(sig); + + SetNumberOfArguments(Signature::GetNumberOfArguments(signature)); +} + +void VMMethod::MarkReferences() { + if (gcfield) return; + VMInvokable::MarkReferences(); + for (int i = 0 ; i < GetNumberOfIndexableFields() ; ++i) { + if (theEntries(i) != NULL) + theEntries(i)->MarkReferences(); + } +} + +int VMMethod::GetNumberOfLocals() const { + return numberOfLocals->GetEmbeddedInteger(); +} + + +void VMMethod::SetNumberOfLocals(int nol) { + numberOfLocals->SetEmbeddedInteger(nol); +} + + +int VMMethod::GetMaximumNumberOfStackElements() const { + return maximumNumberOfStackElements->GetEmbeddedInteger(); +} + + +void VMMethod::SetMaximumNumberOfStackElements(int stel) { + maximumNumberOfStackElements->SetEmbeddedInteger(stel); +} + + +int VMMethod::GetNumberOfArguments() const { + return numberOfArguments->GetEmbeddedInteger(); +} + + +void VMMethod::SetNumberOfArguments(int noa) { + numberOfArguments->SetEmbeddedInteger(noa); +} + + +int VMMethod::GetNumberOfBytecodes() const { + return bcLength->GetEmbeddedInteger(); +} + + +void VMMethod::operator()(pVMFrame frame) { + pVMFrame frm = _UNIVERSE->GetInterpreter()->PushNewFrame(this); + frm->CopyArgumentsFrom(frame); +} + + +void VMMethod::SetHolderAll(pVMClass hld) { + for (int i = 0; i < this->GetNumberOfIndexableFields(); ++i) { + pVMObject o = GetIndexableField(i); + pVMInvokable vmi = DynamicConvert(o); + if ( vmi != NULL) { + vmi->SetHolder(hld); + } + } +} + + +pVMObject VMMethod::GetConstant(int indx) const { + uint8_t bc = _BC[indx+1]; + if (bc >= this->GetNumberOfIndexableFields()) { + cout << "Error: Constant index out of range" << endl; + return NULL; + } + return this->GetIndexableField(bc); +} + +uint8_t& VMMethod::operator[](int indx) const { + return _BC[indx]; +} + +uint8_t VMMethod::GetBytecode(int indx) const { + return _BC[indx]; +} + + +void VMMethod::SetBytecode(int indx, uint8_t val) { + _BC[indx] = val; +} + + +//VMArray Methods +pVMArray VMMethod::CopyAndExtendWith(pVMObject item) const { + size_t fields = this->GetNumberOfIndexableFields(); + pVMArray result = _UNIVERSE->NewArray(fields+1); + this->CopyIndexableFieldsTo(result); + (*result)[fields] = item; + return result; +} + + +pVMObject VMMethod::GetIndexableField(int idx) const { + if (idx > this->GetNumberOfIndexableFields()-1 || idx < 0) { + cout << "Array index out of bounds: Accessing " << idx + << ", but only " << GetNumberOfIndexableFields()-1 + << " entries are available\n"; + _UNIVERSE->ErrorExit("Array index out of bounds exception"); + } + return theEntries(idx); +} + + +void VMMethod::CopyIndexableFieldsTo(pVMArray to) const { + for (int i = 0; i < this->GetNumberOfIndexableFields(); ++i) { + (*to)[i] = this->GetIndexableField(i); + } + +} + +void VMMethod::SetIndexableField(int idx, pVMObject item) { + if (idx > this->GetNumberOfIndexableFields()-1 || idx < 0) { + cout << "Array index out of bounds: Accessing " << idx + << ", but there is only space for " + << this->GetNumberOfIndexableFields() + << " entries available\n"; + _UNIVERSE->ErrorExit("Array index out of bounds exception"); + } + theEntries(idx) = item; +} + + +int VMMethod::GetNumberOfIndexableFields() const { + //cannot be done using GetAdditionalSpaceConsumption, + //as bytecodes need space, too, and there might be padding + return this->numberOfConstants->GetEmbeddedInteger(); +} + diff --git a/src/vmobjects/VMMethod.h b/src/vmobjects/VMMethod.h new file mode 100644 index 0000000..521d59c --- /dev/null +++ b/src/vmobjects/VMMethod.h @@ -0,0 +1,95 @@ +#pragma once +#ifndef VMMETHOD_H_ +#define VMMETHOD_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + +#include + +#include "VMInvokable.h" + +class VMArray; +class VMObject; +class VMInteger; +class MethodGenerationContext; +class VMFrame; + +class VMMethod : public VMInvokable { + +public: + VMMethod(int bcCount, int numberOfConstants, int nof = 0); + + virtual int GetNumberOfLocals() const; + virtual void SetNumberOfLocals(int nol); + virtual int GetMaximumNumberOfStackElements() const; + virtual void SetMaximumNumberOfStackElements(int stel); + virtual int GetNumberOfArguments() const; + virtual void SetNumberOfArguments(int); + virtual int GetNumberOfBytecodes() const; + virtual void SetHolderAll(pVMClass hld); + virtual pVMObject GetConstant(int indx) const; + virtual uint8_t GetBytecode(int indx) const; + virtual void SetBytecode(int indx, uint8_t); + virtual void MarkReferences(); + virtual int GetNumberOfIndexableFields() const; + + void SetIndexableField(int idx, pVMObject item); + + //VMArray Methods.... + + + pVMArray CopyAndExtendWith(pVMObject) const; + void CopyIndexableFieldsTo(pVMArray) const; + + /// Methods are considered byte arrays with meta data. + // So the index operator returns the bytecode at the index. + // Not really used because it violates the C++ idiom to + // implement operators in a "natural" way. Does not really + // seem so natural to do this. + uint8_t& operator[](int indx) const; + + //-----------VMInvokable-------------// + //operator "()" to invoke the method + virtual void operator()(pVMFrame frame); + + virtual void SetSignature(pVMSymbol sig); + + +private: + pVMObject GetIndexableField(int idx) const; + + pVMInteger numberOfLocals; + pVMInteger maximumNumberOfStackElements; + pVMInteger bcLength; + pVMInteger numberOfArguments; + pVMInteger numberOfConstants; + + static const int VMMethodNumberOfFields; +}; + + +#endif diff --git a/src/vmobjects/VMObject.cpp b/src/vmobjects/VMObject.cpp new file mode 100644 index 0000000..918d7c0 --- /dev/null +++ b/src/vmobjects/VMObject.cpp @@ -0,0 +1,149 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMObject.h" +#include "VMClass.h" +#include "VMSymbol.h" +#include "VMFrame.h" +#include "VMInvokable.h" + + +//clazz is the only field of VMObject so +const int VMObject::VMObjectNumberOfFields = 1; + +VMObject::VMObject( int numberOfFields ) { + //this line would be needed if the VMObject** is used instead of the macro: + //FIELDS = (pVMObject*)&clazz; + this->SetNumberOfFields(numberOfFields + VMObjectNumberOfFields); + gcfield = 0; + hash = (int32_t)this; + //Object size is set by the heap +} + + +void VMObject::SetNumberOfFields(int nof) { + this->numberOfFields = nof; + + for (int i = 0; i < nof ; ++i) { + this->SetField(i, nilObject); + } +} + + + + +void VMObject::Send(StdString selectorString, pVMObject* arguments, int argc) { + pVMSymbol selector = _UNIVERSE->SymbolFor(selectorString); + pVMFrame frame = _UNIVERSE->GetInterpreter()->GetFrame(); + frame->Push(this); + + for(int i = 0; i < argc; ++i) { + frame->Push(arguments[i]); + } + + pVMClass cl = this->GetClass(); + pVMInvokable invokable = (pVMInvokable)(cl->LookupInvokable(selector)); + (*invokable)(frame); +} + + +int VMObject::GetDefaultNumberOfFields() const { + return VMObjectNumberOfFields; +} + +pVMClass VMObject::GetClass() const { + return clazz; +} + +void VMObject::SetClass(pVMClass cl) { + clazz = cl; +} + +pVMSymbol VMObject::GetFieldName(int index) const { + return this->clazz->GetInstanceFieldName(index); +} + +int VMObject::GetFieldIndex(pVMSymbol fieldName) const { + return this->clazz->LookupFieldIndex(fieldName); +} + +int VMObject::GetNumberOfFields() const { + return this->numberOfFields; +} + +int32_t VMObject::GetObjectSize() const { + return objectSize; +} + + +int32_t VMObject::GetGCField() const { + return gcfield; +} + + +void VMObject::SetGCField(int32_t value) { + gcfield = value; +} + +void VMObject::SetObjectSize(size_t size) { + objectSize = size; +} + +void VMObject::Assert(bool value) const { + _UNIVERSE->Assert(value); +} + + +pVMObject VMObject::GetField(int index) const { + return FIELDS[index]; +} + + +void VMObject::SetField(int index, pVMObject value) { + FIELDS[index] = value; +} + +//returns the Object's additional memory used (e.g. for Array fields) +int VMObject::GetAdditionalSpaceConsumption() const +{ + //The VM*-Object's additional memory used needs to be calculated. + //It's the total object size MINUS sizeof(VMObject) for basic + //VMObject MINUS the number of fields times sizeof(pVMObject) + return (objectSize - (sizeof(VMObject) + + sizeof(pVMObject) * (this->GetNumberOfFields() - 1))); +} + + +void VMObject::MarkReferences() { + if (this->gcfield) return; + this->SetGCField(1); + for( int i = 0; i < this->GetNumberOfFields(); ++i) { + pVMObject o = (FIELDS[i]); + o->MarkReferences(); + } + +} diff --git a/src/vmobjects/VMObject.h b/src/vmobjects/VMObject.h new file mode 100644 index 0000000..2e72aa6 --- /dev/null +++ b/src/vmobjects/VMObject.h @@ -0,0 +1,139 @@ +#pragma once +#ifndef VMOBJECT_H_ +#define VMOBJECT_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include + +#include "../misc/defs.h" +#include "../memory/Heap.h" +#include "../vm/Universe.h" + +#include "ObjectFormats.h" +#include "VMPointer.h" + +class VMSymbol; +class VMClass; + +#define FIELDS ((pVMObject*)&clazz) + +/* + **************************VMOBJECT**************************** + * __________________________________________________________ * + *| vtable* | 0x00 - 0x03 |* + *|__________________|_______________________________________|* + *| hash | 0x04 - 0x07 |* + *| objectSize | 0x08 - 0x0b |* + *| numberOfFields | 0x0c - 0x0f |* + *| gcField | 0x10 - 0x13 (because of alignment) |* + *| clazz | 0x14 - 0x17 |* + *|__________________|___0x18________________________________|* + * * + ************************************************************** + */ + +class VMObject { + +public: + /* Constructor */ + VMObject(int numberOfFields = 0); + + /* Virtual member functions */ + virtual pVMClass GetClass() const; + virtual void SetClass(pVMClass cl); + virtual pVMSymbol GetFieldName(int index) const; + virtual int GetFieldIndex(pVMSymbol fieldName) const; + virtual int GetNumberOfFields() const; + virtual void SetNumberOfFields(int nof); + virtual int GetDefaultNumberOfFields() const; + virtual void Send(StdString, pVMObject*, int); + virtual pVMObject GetField(int index) const; + virtual void Assert(bool value) const; + virtual void SetField(int index, pVMObject value); + virtual void MarkReferences(); + + virtual void IncreaseGCCount() {}; + virtual void DecreaseGCCount() {}; + + int32_t GetHash() const { return hash; }; + int32_t GetObjectSize() const; + int32_t GetGCField() const; + void SetGCField(int32_t value); + void SetObjectSize(size_t size); + + /* Operators */ + + /** + * usage: new( [, ] ) VMObject( ) + * num_bytes parameter is set by the compiler. + * parameter additional_bytes (a_b) is used for: + * - fields in VMObject, a_b must be set to (numberOfFields*sizeof(pVMObject)) + * - chars in VMString/VMSymbol, a_b must be set to (Stringlength + 1) + * - array size in VMArray; a_b must be set to (size_of_array*sizeof(VMObect*)) + * - fields in VMMethod, a_b must be set to (number_of_bc + number_of_csts*sizeof(pVMObject)) + */ + void* operator new( size_t numBytes, Heap* heap, + unsigned int additionalBytes = 0) { + void* mem = (void*)heap->AllocateObject(numBytes + additionalBytes); + return mem; + } + + void operator delete(void* self, Heap* heap, + unsigned int /*additional_bytes*/) { + heap->Destroy((VMObject*)self); + + } + + void operator delete( void* self, Heap* heap) { + heap->Destroy((VMObject*)self); + + } + + +protected: + int GetAdditionalSpaceConsumption() const; + //VMObject essentials + int32_t hash; + int32_t objectSize; //set by the heap at allocation time + int32_t numberOfFields; + int32_t gcfield; + + //pVMObject* FIELDS; + //Start of fields. All members beyond this point are indexable + //through FIELDS-macro instead of the member above. + //So clazz == FIELDS[0] + pVMClass clazz; +private: + static const int VMObjectNumberOfFields; +}; + + + +#endif diff --git a/src/vmobjects/VMPointer.h b/src/vmobjects/VMPointer.h new file mode 100644 index 0000000..065c152 --- /dev/null +++ b/src/vmobjects/VMPointer.h @@ -0,0 +1,152 @@ +#pragma once + +#ifndef PVMOBJECT_H_ +#define PVMOBJECT_H_ + +#include +#include "../misc/defs.h" + +template +class VMPointer { +public: + //Constructors + //Empty constructor creates NULL pointer + VMPointer() { + pointer = NULL; + }; + VMPointer(T* o) { + pointer = o; + }; + VMPointer(const VMPointer& o) { + pointer = o.GetPointer(); + }; + + //Type conversion constructor. Converts pointer to class U in pointer to class T + template + VMPointer(VMPointer& o) { + pointer = (T*)(o.GetPointer()); + }; + + template + VMPointer(const VMPointer& o) { + pointer = (T*)(o.GetPointer()); + }; + + //null checking + inline bool IsNull() const { return pointer == NULL; }; + + //type conversions + + //conversion to "dumb pointer" of the included type + inline operator T*() { return pointer; }; + + //conversion to reference of the included type + inline T& operator*() { + return *pointer; + }; + + //conversion to const reference of the included type + inline T& operator*() const{ + return *pointer; + }; + + //member access operator + inline T* operator ->() { + return pointer; + }; + //member access operator for const methods + inline T* operator ->() const{ + return pointer; + }; + //assignments + + //allows to assign a "dumb pointer" to a smart pointer of the included type + inline VMPointer& operator =(T* ptr); + inline VMPointer& operator =( T& ptr); + //allows to assign smart pointers of the same type + inline VMPointer& operator =(VMPointer ptr); + + //allows to assign "dumb pointer" of a different (compatible) type + template + VMPointer& operator =(U* ptr) { + pointer = (T*)(ptr); + return *this; + } + + //allows to assign smart pointers of different (compatible) types + template + VMPointer& operator =(VMPointer o){ + //check for self assignment + if ((void*)&o == (void*)this) return *this; + pointer = (T*)(o.GetPointer()); + + return *this; + }; + + //comparing + inline bool operator==(VMPointer o) const{ + return (void*)o.pointer == (void*)pointer; + }; + inline bool operator==(void* ptr) const{ + return (void*)pointer == ptr; + }; + + template + inline bool operator==(VMPointer o) const{ + return (void*)pointer == (void*)o.GetPointer(); + }; + + inline bool operator!=(VMPointer o) const{ + return (void*)o.pointer != (void*)pointer; + }; + inline bool operator!=(void* ptr) const{ + return (void*)pointer != ptr; + }; + template + inline bool operator!=(VMPointer o) const{ + return (void*)pointer != (void*)o.GetPointer(); + }; + + //neccessary to use VMPointers as keys in std::map + inline int operator<(VMPointer o) const { + return (void*)pointer < (void*)o.GetPointer(); + } + + inline T* GetPointer() const{ + return pointer; + } + +protected: + T* pointer; + +}; + +template < class T > +VMPointer& VMPointer::operator =( T& ptr ) +{ + pointer = &ptr; + return *this; +}; + +template < class T > +VMPointer& VMPointer::operator =( T* ptr ) +{ + pointer = ptr; + return *this; +}; + +template +VMPointer& VMPointer::operator =(VMPointer ptr) +{ + if(&ptr == this) return *this; + pointer = ptr.pointer; + return *this; +}; + + + + + +#endif + + diff --git a/src/vmobjects/VMPointerConverter.h b/src/vmobjects/VMPointerConverter.h new file mode 100644 index 0000000..6949558 --- /dev/null +++ b/src/vmobjects/VMPointerConverter.h @@ -0,0 +1,19 @@ +#pragma once + +#ifndef VMPOINTERCONVERTER_H_ +#define VMPOINTERCONVERTER_H_ + +#include "VMPointer.h" + +//This template fucntion converts smart pointer of one type into +//smart pointers of a different type using type checking. +template +static VMPointer DynamicConvert(VMPointer pu) { + TO* ptr = dynamic_cast(pu.GetPointer()); + //if (ptr == NULL) ptr = (T*)Globals::NilObject().GetPointer(); + return VMPointer(ptr); +}; + + +#endif + diff --git a/src/vmobjects/VMPrimitive.cpp b/src/vmobjects/VMPrimitive.cpp new file mode 100644 index 0000000..23302ca --- /dev/null +++ b/src/vmobjects/VMPrimitive.cpp @@ -0,0 +1,86 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMPrimitive.h" +#include "VMSymbol.h" +#include "VMClass.h" + +#include "../vm/Universe.h" + +//needed to instanciate the Routine object for the empty routine +#include "../primitivesCore/Routine.h" + + +pVMPrimitive VMPrimitive::GetEmptyPrimitive( pVMSymbol sig ) { + + pVMPrimitive prim = new (_HEAP) VMPrimitive(sig); + prim->empty = (bool*)1; + prim->SetRoutine(new Routine(prim, &VMPrimitive::EmptyRoutine)); + return prim; +} + +const int VMPrimitive::VMPrimitiveNumberOfFields = 2; + +VMPrimitive::VMPrimitive(pVMSymbol signature) : VMInvokable(VMPrimitiveNumberOfFields) { + _HEAP->StartUninterruptableAllocation(); + //the only class that explicitly does this. + this->SetClass(primitiveClass); + + this->SetSignature(signature); + this->routine = NULL; + this->empty = (bool*)0; + + _HEAP->EndUninterruptableAllocation(); +} + + + +void VMPrimitive::MarkReferences() { + if (gcfield) return; + + this->SetGCField(1); + //explicitly implement marking for primitives, as they include fields + //that should not be marked!!! + for( int i = 0; i < this->GetNumberOfFields(); ++i) { + //HACK to avoid calling MarkReferences() for the bool* + if ((void*)GetField(i) == (void*)this->empty) + continue; + //HACK to avoid calling MarkReferences() for the routine* + if ((void*)GetField(i) == (void*)this->routine) + continue; + GetField(i)->MarkReferences(); + } +} + + +void VMPrimitive::EmptyRoutine( pVMObject _self, pVMFrame /*frame*/ ) { + pVMInvokable self = (pVMInvokable)( _self ); + pVMSymbol sig = self->GetSignature(); + cout << "undefined primitive called: " << sig->GetChars() << endl; +} + + diff --git a/src/vmobjects/VMPrimitive.h b/src/vmobjects/VMPrimitive.h new file mode 100644 index 0000000..7a7ac69 --- /dev/null +++ b/src/vmobjects/VMPrimitive.h @@ -0,0 +1,75 @@ +#pragma once +#ifndef VMPRIMITVE_H_ +#define VMPRIMITVE_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMObject.h" +#include "VMInvokable.h" +#include "PrimitiveRoutine.h" + + +class VMSymbol; + +class VMPrimitive : public VMInvokable { +public: + static pVMPrimitive GetEmptyPrimitive(pVMSymbol sig); + + VMPrimitive(pVMSymbol sig); + + virtual inline bool IsEmpty() const; + virtual inline void SetRoutine(PrimitiveRoutine* rtn); + virtual void MarkReferences(); + virtual void SetEmpty(bool value) { empty = (bool*)value; }; + + //-----------VMInvokable-------// + //operator "()" to invoke the primitive + virtual void operator()(pVMFrame frm) { (*routine)(this, frm); }; + + virtual bool IsPrimitive() const { return true; }; + +private: + void EmptyRoutine(pVMObject self, pVMFrame frame); + + PrimitiveRoutine* routine; + bool* empty; + + static const int VMPrimitiveNumberOfFields; + +}; + +bool VMPrimitive::IsEmpty() const { + return (bool)empty; +} + + +void VMPrimitive::SetRoutine(PrimitiveRoutine* rtn) { + routine = rtn; +} + +#endif diff --git a/src/vmobjects/VMString.cpp b/src/vmobjects/VMString.cpp new file mode 100644 index 0000000..3025681 --- /dev/null +++ b/src/vmobjects/VMString.cpp @@ -0,0 +1,76 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include +#include + +#include "VMString.h" +#include "VMInteger.h" + +//this macro could replace the chars member variable +//#define CHARS ((char*)&clazz+sizeof(pVMObject)) + +const int VMString::VMStringNumberOfFields = 0; + +VMString::VMString(const char* str) : VMObject(VMStringNumberOfFields) { + //set the chars-pointer to point at the position of the first character + chars = (char*)&chars+sizeof(char*); + + size_t i = 0; + for (; i < strlen(str); ++i) { + chars[i] = str[i]; + } + chars[i] = '\0'; + +} + + +VMString::VMString( const StdString& s ): VMObject(VMStringNumberOfFields) { + //set the chars-pointer to point at the position of the first character + chars = (char*)&chars+sizeof(char*); + size_t i = 0; + for (; i < s.length(); ++i) { + chars[i] = s[i]; + } + chars[i] = '\0'; +} + +int VMString::GetStringLength() const { + //get the additional memory allocated by this object and substract one + //for the '0' character and four for the char* + return this->GetAdditionalSpaceConsumption() - 4 - 1; +} + + +StdString VMString::GetStdString() const { + if (chars == 0) return StdString(""); + return StdString(chars); +} + + + + diff --git a/src/vmobjects/VMString.h b/src/vmobjects/VMString.h new file mode 100644 index 0000000..55bf6a4 --- /dev/null +++ b/src/vmobjects/VMString.h @@ -0,0 +1,56 @@ +#pragma once +#ifndef VMSTRING_H_ +#define VMSTRING_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include "VMObject.h" + +class VMString : public VMObject { +public: + VMString( const char* str ); + VMString( const StdString& s ); + + inline char* GetChars() const; + StdString GetStdString() const; + int GetStringLength() const; + + +protected: + //this could be replaced by the CHARS macro in VMString.cpp + //in order to decrease the object size + char* chars; + +private: + static const int VMStringNumberOfFields; +}; + +char* VMString::GetChars() const { + return chars; +} +#endif diff --git a/src/vmobjects/VMSymbol.cpp b/src/vmobjects/VMSymbol.cpp new file mode 100644 index 0000000..004682c --- /dev/null +++ b/src/vmobjects/VMSymbol.cpp @@ -0,0 +1,104 @@ +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include + +#include "VMSymbol.h" +#include "VMInteger.h" + + +VMSymbol::VMSymbol(const char* str) : VMString(str) { +} + + +VMSymbol::VMSymbol( const StdString& s ): VMString(s) { +} + + +StdString VMSymbol::GetPlainString() const { + ostringstream str; + char* chars = this->GetChars(); + for(size_t i=0; i <= (size_t)this->GetStringLength(); i++) { + char c = chars[i]; + switch (c) { + case '~': + str << "tilde"; + break; + case '&': + str << "and"; + break; + case '|': + str << "bar"; + break; + case '*': + str << "star"; + break; + case '/': + str << "slash"; + break; + case '@': + str << "at"; + break; + case '+': + str << "plus"; + break; + case '-': + str << "minus"; + break; + case '=': + str << "equal"; + break; + case '>': + str << "greaterthan" ; + break; + case '<': + str << "lowerthan"; + break; + case ',': + str << "comma"; + break; + case '%': + str << "percent"; + break; + case '\\': + str << "backslash"; + break; + case ':': + str << '_'; + break; + default: + if (c != 0) { + str << c; + } + break; + } + } + StdString st = str.str(); + + return st; +} + diff --git a/src/vmobjects/VMSymbol.h b/src/vmobjects/VMSymbol.h new file mode 100644 index 0000000..94ca7ad --- /dev/null +++ b/src/vmobjects/VMSymbol.h @@ -0,0 +1,49 @@ +#pragma once +#ifndef VMSYMBOL_H_ +#define VMSYMBOL_H_ + +/* + * + * +Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann +Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany +http://www.hpi.uni-potsdam.de/swa/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + + +#include + +#include "VMString.h" +#include "VMObject.h" + +class VMInteger; + +class VMSymbol : public VMString { + +public: + VMSymbol( const char* str ); + VMSymbol( const StdString& s ); + virtual StdString GetPlainString() const; + +}; + + +#endif