├── .antlr-eclipse
├── .checkstyle
├── .checkstyle_checks.xml
├── .checkstyle_suppressions.xml
├── .classpath
├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── .gitlab-ci.yml
├── .gitmodules
├── .project
├── .settings
├── org.deved.antlride.core.prefs
├── org.eclipse.jdt.core.prefs
└── org.eclipse.jdt.ui.prefs
├── AUTHORS
├── Examples
├── LICENSE
├── Makefile
├── README.md
├── Smalltalk
├── TestSuite
├── awfy-test.conf
├── build.xml
├── rebench.conf
├── som.sh
├── src
└── som
│ ├── compiler
│ ├── BytecodeGenerator.java
│ ├── ClassGenerationContext.java
│ ├── Disassembler.java
│ ├── Lexer.java
│ ├── MethodGenerationContext.java
│ ├── Parser.java
│ ├── ProgramDefinitionError.java
│ ├── SourcecodeCompiler.java
│ ├── Symbol.java
│ └── Triplet.java
│ ├── interpreter
│ ├── Bytecodes.java
│ ├── Frame.java
│ └── Interpreter.java
│ ├── primitives
│ ├── ArrayPrimitives.java
│ ├── BlockPrimitives.java
│ ├── ClassPrimitives.java
│ ├── DoublePrimitives.java
│ ├── IntegerPrimitives.java
│ ├── MethodPrimitives.java
│ ├── ObjectPrimitives.java
│ ├── PrimitivePrimitives.java
│ ├── Primitives.java
│ ├── StringPrimitives.java
│ ├── SymbolPrimitives.java
│ └── SystemPrimitives.java
│ ├── vm
│ ├── Shell.java
│ └── Universe.java
│ └── vmobjects
│ ├── SAbstractObject.java
│ ├── SArray.java
│ ├── SBigInteger.java
│ ├── SBlock.java
│ ├── SClass.java
│ ├── SDouble.java
│ ├── SInteger.java
│ ├── SInvokable.java
│ ├── SMethod.java
│ ├── SNumber.java
│ ├── SObject.java
│ ├── SPrimitive.java
│ ├── SString.java
│ └── SSymbol.java
└── tests
└── som
├── compiler
└── LexerTests.java
└── tests
├── BasicInterpreterTests.java
└── SomTests.java
/.antlr-eclipse:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.checkstyle:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.checkstyle_checks.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
--------------------------------------------------------------------------------
/.checkstyle_suppressions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | test_som:
7 | runs-on: ubuntu-24.04 # ubuntu-latest
8 | steps:
9 | - name: Checkout
10 | uses: actions/checkout@v4
11 | with:
12 | submodules: true
13 |
14 | - name: Tests
15 | run: |
16 | ant test
17 |
18 | - name: SomSom Tests
19 | run: |
20 | ./som.sh -cp core-lib/Smalltalk:core-lib/TestSuite:core-lib/SomSom/src/compiler:core-lib/SomSom/src/vm:core-lib/SomSom/src/vmobjects:core-lib/SomSom/src/interpreter:core-lib/SomSom/src/primitives \
21 | core-lib/SomSom/tests/SomSomTests.som
22 |
23 | - name: CheckStyle
24 | run: |
25 | ant checkstyle
26 |
27 | - name: Download Eclipse
28 | run: |
29 | export ECLIPSE_TAR=eclipse.tar.gz
30 | export ECLIPSE_URL=https://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops4/R-4.22-202111241800/eclipse-SDK-4.22-linux-gtk-x86_64.tar.gz
31 | wget ${ECLIPSE_URL} -O ${ECLIPSE_TAR}
32 | tar -C ${GITHUB_WORKSPACE}/.. -xzf ${ECLIPSE_TAR}
33 |
34 | - name: Check Eclipse Format
35 | run: |
36 | export ECLIPSE_EXE=${GITHUB_WORKSPACE}/../eclipse/eclipse
37 | ant eclipseformat
38 |
39 | - name: Checkout AWFY
40 | uses: actions/checkout@v4
41 | with:
42 | repository: smarr/are-we-fast-yet
43 | path: are-we-fast-yet
44 |
45 | - name: AWFY Test Run
46 | run: |
47 | pwd
48 | export JAVA_HOME=$JAVA_HOME_8_X64
49 | pip install ReBench
50 | rebench awfy-test.conf
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 |
3 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | stages:
2 | - test-benchmark
3 |
4 | variables:
5 | PYTHONUNBUFFERED: "true"
6 |
7 | before_script:
8 | - git submodule update --init
9 |
10 | som:
11 | stage: test-benchmark
12 | tags: [benchmarks, infinity]
13 | script:
14 | - ant test
15 | - ./som.sh -cp ./Smalltalk ./TestSuite/TestHarness.som
16 | - ./som.sh -cp core-lib/Smalltalk:core-lib/TestSuite:core-lib/SomSom/src/compiler:core-lib/SomSom/src/vm:core-lib/SomSom/src/vmobjects:core-lib/SomSom/src/interpreter:core-lib/SomSom/src/primitives core-lib/SomSom/tests/SomSomTests.som
17 | - ant checkstyle
18 |
19 | - rebench --experiment="CI ID $CI_PIPELINE_ID" --branch="$CI_COMMIT_REF_NAME" -c rebench.conf all
20 | - rebench --experiment="CI ID $CI_PIPELINE_ID" --report-completion rebench.conf
21 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "core-lib"]
2 | path = core-lib
3 | url = https://github.com/SOM-st/SOM.git
4 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | SOM-java
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.dltk.core.scriptbuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.jdt.core.javabuilder
15 |
16 |
17 |
18 |
19 | net.sf.eclipsecs.core.CheckstyleBuilder
20 |
21 |
22 |
23 |
24 |
25 | org.eclipse.jdt.core.javanature
26 | net.sf.eclipsecs.core.CheckstyleNature
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.settings/org.deved.antlride.core.prefs:
--------------------------------------------------------------------------------
1 | #Thu Jul 23 08:49:05 CEST 2009
2 | antlr_core_mark_generated_resources_as_derived=false
3 | eclipse.preferences.version=1
4 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.ui.prefs:
--------------------------------------------------------------------------------
1 | cleanup.add_default_serial_version_id=true
2 | cleanup.add_generated_serial_version_id=false
3 | cleanup.add_missing_annotations=true
4 | cleanup.add_missing_deprecated_annotations=true
5 | cleanup.add_missing_methods=false
6 | cleanup.add_missing_nls_tags=false
7 | cleanup.add_missing_override_annotations=true
8 | cleanup.add_missing_override_annotations_interface_methods=true
9 | cleanup.add_serial_version_id=false
10 | cleanup.always_use_blocks=true
11 | cleanup.always_use_parentheses_in_expressions=false
12 | cleanup.always_use_this_for_non_static_field_access=false
13 | cleanup.always_use_this_for_non_static_method_access=false
14 | cleanup.convert_functional_interfaces=false
15 | cleanup.convert_to_enhanced_for_loop=false
16 | cleanup.correct_indentation=false
17 | cleanup.format_source_code=true
18 | cleanup.format_source_code_changes_only=false
19 | cleanup.insert_inferred_type_arguments=false
20 | cleanup.make_local_variable_final=true
21 | cleanup.make_parameters_final=false
22 | cleanup.make_private_fields_final=true
23 | cleanup.make_type_abstract_if_missing_method=false
24 | cleanup.make_variable_declarations_final=false
25 | cleanup.never_use_blocks=false
26 | cleanup.never_use_parentheses_in_expressions=true
27 | cleanup.organize_imports=true
28 | cleanup.qualify_static_field_accesses_with_declaring_class=false
29 | cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
30 | cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
31 | cleanup.qualify_static_member_accesses_with_declaring_class=true
32 | cleanup.qualify_static_method_accesses_with_declaring_class=false
33 | cleanup.remove_private_constructors=true
34 | cleanup.remove_redundant_type_arguments=false
35 | cleanup.remove_trailing_whitespaces=true
36 | cleanup.remove_trailing_whitespaces_all=true
37 | cleanup.remove_trailing_whitespaces_ignore_empty=false
38 | cleanup.remove_unnecessary_casts=true
39 | cleanup.remove_unnecessary_nls_tags=true
40 | cleanup.remove_unused_imports=true
41 | cleanup.remove_unused_local_variables=false
42 | cleanup.remove_unused_private_fields=true
43 | cleanup.remove_unused_private_members=false
44 | cleanup.remove_unused_private_methods=true
45 | cleanup.remove_unused_private_types=true
46 | cleanup.sort_members=false
47 | cleanup.sort_members_all=false
48 | cleanup.use_anonymous_class_creation=false
49 | cleanup.use_blocks=false
50 | cleanup.use_blocks_only_for_return_and_throw=false
51 | cleanup.use_lambda=true
52 | cleanup.use_parentheses_in_expressions=false
53 | cleanup.use_this_for_non_static_field_access=false
54 | cleanup.use_this_for_non_static_field_access_only_if_necessary=true
55 | cleanup.use_this_for_non_static_method_access=false
56 | cleanup.use_this_for_non_static_method_access_only_if_necessary=true
57 | cleanup_profile=_SOM
58 | cleanup_settings_version=2
59 | eclipse.preferences.version=1
60 | editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
61 | formatter_profile=_SOM
62 | formatter_settings_version=12
63 | internal.default.compliance=default
64 | sp_cleanup.add_default_serial_version_id=true
65 | sp_cleanup.add_generated_serial_version_id=false
66 | sp_cleanup.add_missing_annotations=true
67 | sp_cleanup.add_missing_deprecated_annotations=true
68 | sp_cleanup.add_missing_methods=false
69 | sp_cleanup.add_missing_nls_tags=false
70 | sp_cleanup.add_missing_override_annotations=true
71 | sp_cleanup.add_missing_override_annotations_interface_methods=true
72 | sp_cleanup.add_serial_version_id=false
73 | sp_cleanup.always_use_blocks=true
74 | sp_cleanup.always_use_parentheses_in_expressions=false
75 | sp_cleanup.always_use_this_for_non_static_field_access=false
76 | sp_cleanup.always_use_this_for_non_static_method_access=false
77 | sp_cleanup.convert_functional_interfaces=false
78 | sp_cleanup.convert_to_enhanced_for_loop=false
79 | sp_cleanup.correct_indentation=false
80 | sp_cleanup.format_source_code=false
81 | sp_cleanup.format_source_code_changes_only=false
82 | sp_cleanup.insert_inferred_type_arguments=false
83 | sp_cleanup.make_local_variable_final=false
84 | sp_cleanup.make_parameters_final=true
85 | sp_cleanup.make_private_fields_final=false
86 | sp_cleanup.make_type_abstract_if_missing_method=false
87 | sp_cleanup.make_variable_declarations_final=true
88 | sp_cleanup.never_use_blocks=false
89 | sp_cleanup.never_use_parentheses_in_expressions=true
90 | sp_cleanup.on_save_use_additional_actions=true
91 | sp_cleanup.organize_imports=true
92 | sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
93 | sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
94 | sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
95 | sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
96 | sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
97 | sp_cleanup.remove_private_constructors=true
98 | sp_cleanup.remove_redundant_type_arguments=false
99 | sp_cleanup.remove_trailing_whitespaces=true
100 | sp_cleanup.remove_trailing_whitespaces_all=true
101 | sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
102 | sp_cleanup.remove_unnecessary_casts=true
103 | sp_cleanup.remove_unnecessary_nls_tags=false
104 | sp_cleanup.remove_unused_imports=true
105 | sp_cleanup.remove_unused_local_variables=false
106 | sp_cleanup.remove_unused_private_fields=true
107 | sp_cleanup.remove_unused_private_members=false
108 | sp_cleanup.remove_unused_private_methods=true
109 | sp_cleanup.remove_unused_private_types=true
110 | sp_cleanup.sort_members=false
111 | sp_cleanup.sort_members_all=false
112 | sp_cleanup.use_anonymous_class_creation=false
113 | sp_cleanup.use_blocks=true
114 | sp_cleanup.use_blocks_only_for_return_and_throw=false
115 | sp_cleanup.use_lambda=false
116 | sp_cleanup.use_parentheses_in_expressions=false
117 | sp_cleanup.use_this_for_non_static_field_access=false
118 | sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
119 | sp_cleanup.use_this_for_non_static_method_access=false
120 | sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
121 | sp_cleanup.use_type_arguments=false
122 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | This file lists all people who have contributed to the SOM VM.
2 |
3 | SOM was originally implemented at the University of Aarhus (Denmark) in
4 | 2001/2002. The implementation of SOM was done by Jakob Roland Andersen, Kasper
5 | Verdich Lund, Lars Bak, Mads Torgersen, and Ulrik Pagh Schultz. They also
6 | wrote the original versions of the SOM Smalltalk libraries, test suites, and
7 | benchmarks, that are (in extended versions) bundled with SOM.
8 |
9 | SOM was used by Michael Haupt in courses on virtual machines at Lancaster
10 | University and Technische Universitaet Darmstadt (Germany) in VM courses in
11 | 2006. During that time, some changes were applied to SOM by Michael Haupt and
12 | Sebastian Kanthak.
13 |
14 | SOM is currently maintained by Michael Haupt at the Hasso-Plattner-Institut,
15 | University of Potsdam, Germany.
16 |
17 | 2009-08-14, Michael Haupt
18 | michael.haupt@hpi.uni-potsdam.de
--------------------------------------------------------------------------------
/Examples:
--------------------------------------------------------------------------------
1 | core-lib/Examples
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
2 | Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
3 | http://www.hpi.uni-potsdam.de/swa/
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env make -f
2 |
3 | all: compile
4 |
5 | clean:
6 | ant clean
7 |
8 | compile: build/som.jar
9 |
10 | build/som.jar:
11 | ant jar
12 |
13 | test:
14 | ant test
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SOM - Simple Object Machine
2 | ===========================
3 |
4 | SOM is a minimal Smalltalk dialect used to teach VM construction at the [Hasso
5 | Plattner Institute][SOM]. It was originally built at the University of Århus
6 | (Denmark) where it was also used for teaching.
7 |
8 | Currently, implementations exist for Java (SOM), C (CSOM), C++ (SOM++), and
9 | Squeak/Pharo Smalltalk (AweSOM).
10 |
11 | A simple SOM Hello World looks like:
12 |
13 | ```Smalltalk
14 | Hello = (
15 | run = (
16 | 'Hello World!' println.
17 | )
18 | )
19 | ```
20 |
21 | This repository contains a plain Java implementation of SOM, including an implementation of the SOM standard library. Please see the [main project page][SOMst] for links to the VM implementation.
22 |
23 | Make sure to initialize the shared Smalltalk standard library, tests, and examples by importing the git submodule:
24 |
25 | $ git submodule update --init
26 |
27 | To build and run SOM, Java 8 or newer is required.
28 |
29 | SOM can be built with Ant:
30 |
31 | $ ant jar
32 |
33 | Afterwards, the tests can be executed with:
34 |
35 | $ ./som.sh -cp Smalltalk TestSuite/TestHarness.som
36 |
37 | or with:
38 |
39 | $ ant test
40 |
41 | A simple Hello World program is executed with:
42 |
43 | $ ./som.sh -cp Smalltalk Examples/Hello.som
44 |
45 |
46 | Information on previous authors are included in the AUTHORS file. This code is
47 | distributed under the MIT License. Please see the LICENSE file for details.
48 |
49 | Build Status
50 | ------------
51 |
52 | Thanks to Travis CI, all commits of this repository are tested.
53 | The current build status is: [](https://travis-ci.org/SOM-st/som-java)
54 |
55 | [SOM]: http://www.hpi.uni-potsdam.de/hirschfeld/projects/som/
56 | [SOMst]: https://travis-ci.org/SOM-st/
57 |
--------------------------------------------------------------------------------
/Smalltalk:
--------------------------------------------------------------------------------
1 | core-lib/Smalltalk
--------------------------------------------------------------------------------
/TestSuite:
--------------------------------------------------------------------------------
1 | core-lib/TestSuite
--------------------------------------------------------------------------------
/awfy-test.conf:
--------------------------------------------------------------------------------
1 | # -*- mode: yaml -*-
2 | # Config file for ReBench
3 | default_experiment: all
4 | default_data_file: 'benchmark.data'
5 |
6 | runs:
7 | iterations: 1
8 | invocations: 1
9 |
10 | # definition of benchmark suites
11 | benchmark_suites:
12 | test-som:
13 | gauge_adapter: RebenchLog
14 | command: " -cp .:Core:CD:DeltaBlue:Havlak:Json:NBody:Richards:../../../core-lib/Smalltalk Harness.som %(benchmark)s 1 "
15 | location: are-we-fast-yet/benchmarks/SOM
16 | max_invocation_time: 240
17 | benchmarks: &BENCHMARKS
18 | - DeltaBlue:
19 | extra_args: 1
20 | - Richards:
21 | extra_args: 1
22 | - Json:
23 | extra_args: 1
24 | - CD:
25 | extra_args: 10
26 | - Havlak:
27 | extra_args: 1
28 |
29 | - Bounce:
30 | extra_args: 1
31 | - List:
32 | extra_args: 1
33 | - Mandelbrot:
34 | extra_args: 1
35 | - NBody:
36 | extra_args: 1
37 | - Permute:
38 | extra_args: 1
39 | - Queens:
40 | extra_args: 1
41 | - Sieve:
42 | extra_args: 1
43 | - Storage:
44 | extra_args: 1
45 | - Towers:
46 | extra_args: 1
47 |
48 | executors:
49 | SOM:
50 | path: .
51 | executable: som.sh
52 |
53 | experiments:
54 | test-awfy:
55 | description: |
56 | This is a test run of the Are We Fast Yet benchmarks.
57 | It's expected that the repository is located in the are-we-fast-yet folder.
58 | suites:
59 | - test-som
60 | executions:
61 | - SOM
62 |
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
63 |
66 |
67 |
68 |
69 |
70 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/rebench.conf:
--------------------------------------------------------------------------------
1 | # -*- mode: yaml -*-
2 | # Config file for ReBench
3 | default_experiment: all
4 | default_data_file: 'rebench.data'
5 |
6 | reporting:
7 | # Benchmark results will be reported to ReBenchDB
8 | rebenchdb:
9 | # this url needs to point to the API endpoint
10 | db_url: https://rebench.stefan-marr.de/rebenchdb
11 | repo_url: https://github.com/smarr/SOM-java
12 | record_all: true # make sure everything is recorded
13 | project_name: SOM
14 |
15 | runs:
16 | max_invocation_time: 120
17 |
18 | benchmark_suites:
19 | macro:
20 | gauge_adapter: RebenchLog
21 | command: &MACRO_CMD "-cp Smalltalk:Examples/Benchmarks/Richards:Examples/Benchmarks/DeltaBlue:Examples/Benchmarks/NBody:Examples/Benchmarks/Json:Examples/Benchmarks/GraphSearch Examples/Benchmarks/BenchmarkHarness.som %(benchmark)s %(iterations)s "
22 | iterations: 10
23 | benchmarks:
24 | - Richards: {extra_args: 1}
25 | - DeltaBlue: {extra_args: 50}
26 | - NBody: {extra_args: 500}
27 | - JsonSmall: {extra_args: 1}
28 | - GraphSearch: {extra_args: 4}
29 | - PageRank: {extra_args: 40}
30 |
31 | micro:
32 | gauge_adapter: RebenchLog
33 | command: "-cp Smalltalk:Examples/Benchmarks/LanguageFeatures Examples/Benchmarks/BenchmarkHarness.som %(benchmark)s %(iterations)s "
34 | iterations: 10
35 | benchmarks:
36 | - Fannkuch: {extra_args: 6}
37 | - Fibonacci: {extra_args: 3}
38 | - Dispatch: {extra_args: 2}
39 | - Bounce: {extra_args: 2}
40 | - Loop: {extra_args: 5}
41 | - Permute: {extra_args: 3}
42 | - Queens: {extra_args: 2}
43 | - List: {extra_args: 2}
44 | - Recurse: {extra_args: 3}
45 | - Storage: {extra_args: 1}
46 | - Sieve: {extra_args: 4}
47 | - BubbleSort: {extra_args: 3}
48 | - QuickSort: {extra_args: 1}
49 | - Sum: {extra_args: 2}
50 | - Towers: {extra_args: 2}
51 | - TreeSort: {extra_args: 1}
52 | - IntegerLoop: {extra_args: 2}
53 | - FieldLoop: {extra_args: 1}
54 | - WhileLoop: {extra_args: 10}
55 | - Mandelbrot: {extra_args: 30}
56 |
57 | micro-somsom:
58 | gauge_adapter: RebenchLog
59 | command: "-cp Smalltalk:Examples/Benchmarks/LanguageFeatures Examples/Benchmarks/BenchmarkHarness.som %(benchmark)s %(iterations)s 0 "
60 | iterations: 1
61 | benchmarks:
62 | - Loop: {extra_args: 1}
63 | - Queens: {extra_args: 1}
64 | - List: {extra_args: 1}
65 | - Recurse: {extra_args: 1}
66 | - Mandelbrot: {extra_args: 3}
67 |
68 | interpreter:
69 | description: Basic interpreter benchmarks for comparing performance of most basic concepts.
70 | gauge_adapter: RebenchLog
71 | invocations: 5
72 | command: "-cp Smalltalk:Examples/Benchmarks/Interpreter Examples/Benchmarks/BenchmarkHarness.som %(benchmark)s %(iterations)s 1"
73 | benchmarks:
74 | - ArgRead
75 | - ArrayReadConst
76 | - ArrayWriteConstConst
77 | - BlockSend0ConstReturn
78 | - Const
79 | - FieldConstWrite
80 | - FieldRead
81 | - FieldReadIncWrite
82 | - FieldReadWrite
83 | - GlobalRead
84 | - LocalConstWrite
85 | - LocalRead
86 | - LocalReadIncWrite
87 | - LocalReadWrite
88 | - SelfSend0
89 | - SelfSend0BlockConstNonLocalReturn
90 |
91 | executors:
92 | som: {path: ., executable: som.sh}
93 | somsom:
94 | path: .
95 | executable: som.sh
96 | args: "-cp core-lib/Smalltalk:core-lib/TestSuite:core-lib/SomSom/src/compiler:core-lib/SomSom/src/vm:core-lib/SomSom/src/vmobjects:core-lib/SomSom/src/interpreter:core-lib/SomSom/src/primitives core-lib/SomSom/src/vm/Main.som"
97 |
98 |
99 | # define the benchmarks to be executed for a re-executable benchmark run
100 | experiments:
101 | SOM-java:
102 | description: All benchmarks on SOM (Java)
103 | suites:
104 | - micro
105 | - macro
106 | - interpreter
107 | executions:
108 | - som
109 | SomSom:
110 | description: Running a few SomSom benchmarks on SOM (Java)
111 | suites:
112 | - micro-somsom
113 | executions:
114 | - somsom
115 |
--------------------------------------------------------------------------------
/som.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | pushd `dirname $0` > /dev/null
3 | SCRIPT_PATH=`pwd`
4 | popd > /dev/null
5 |
6 | java -server -cp "${SCRIPT_PATH}/build/classes":"${SCRIPT_PATH}/build/som.jar" som.vm.Universe "$@"
7 |
--------------------------------------------------------------------------------
/src/som/compiler/BytecodeGenerator.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Michael Haupt, github@haupz.de
3 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
4 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
5 | * http://www.hpi.uni-potsdam.de/swa/
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package som.compiler;
27 |
28 | import static som.interpreter.Bytecodes.*;
29 |
30 | import som.vmobjects.SAbstractObject;
31 | import som.vmobjects.SMethod;
32 | import som.vmobjects.SSymbol;
33 |
34 |
35 | public class BytecodeGenerator {
36 |
37 | public void emitPOP(final MethodGenerationContext mgenc) {
38 | emit1(mgenc, POP);
39 | }
40 |
41 | public void emitPUSHARGUMENT(final MethodGenerationContext mgenc, final byte idx,
42 | final byte ctx) {
43 | emit3(mgenc, PUSH_ARGUMENT, idx, ctx);
44 | }
45 |
46 | public void emitRETURNLOCAL(final MethodGenerationContext mgenc) {
47 | emit1(mgenc, RETURN_LOCAL);
48 | }
49 |
50 | public void emitRETURNNONLOCAL(final MethodGenerationContext mgenc) {
51 | emit1(mgenc, RETURN_NON_LOCAL);
52 | }
53 |
54 | public void emitDUP(final MethodGenerationContext mgenc) {
55 | emit1(mgenc, DUP);
56 | }
57 |
58 | public void emitPUSHBLOCK(final MethodGenerationContext mgenc, final SMethod blockMethod) {
59 | emit2(mgenc, PUSH_BLOCK, mgenc.findLiteralIndex(blockMethod));
60 | }
61 |
62 | public void emitPUSHLOCAL(final MethodGenerationContext mgenc, final byte idx,
63 | final byte ctx) {
64 | assert idx >= 0;
65 | emit3(mgenc, PUSH_LOCAL, idx, ctx);
66 | }
67 |
68 | public void emitPUSHFIELD(final MethodGenerationContext mgenc, final SSymbol fieldName) {
69 | assert mgenc.hasField(fieldName);
70 | emit2(mgenc, PUSH_FIELD, mgenc.getFieldIndex(fieldName));
71 | }
72 |
73 | public void emitPUSHGLOBAL(final MethodGenerationContext mgenc, final SSymbol global) {
74 | emit2(mgenc, PUSH_GLOBAL, mgenc.findLiteralIndex(global));
75 | }
76 |
77 | public void emitPOPARGUMENT(final MethodGenerationContext mgenc, final byte idx,
78 | final byte ctx) {
79 | emit3(mgenc, POP_ARGUMENT, idx, ctx);
80 | }
81 |
82 | public void emitPOPLOCAL(final MethodGenerationContext mgenc, final byte idx,
83 | final byte ctx) {
84 | emit3(mgenc, POP_LOCAL, idx, ctx);
85 | }
86 |
87 | public void emitPOPFIELD(final MethodGenerationContext mgenc, final SSymbol fieldName) {
88 | assert mgenc.hasField(fieldName);
89 | emit2(mgenc, POP_FIELD, mgenc.getFieldIndex(fieldName));
90 | }
91 |
92 | public void emitSUPERSEND(final MethodGenerationContext mgenc, final SSymbol msg) {
93 | emit2(mgenc, SUPER_SEND, mgenc.findLiteralIndex(msg));
94 | }
95 |
96 | public void emitSEND(final MethodGenerationContext mgenc, final SSymbol msg) {
97 | emit2(mgenc, SEND, mgenc.findLiteralIndex(msg));
98 | }
99 |
100 | public void emitPUSHCONSTANT(final MethodGenerationContext mgenc,
101 | final SAbstractObject lit) {
102 | emit2(mgenc, PUSH_CONSTANT, mgenc.findLiteralIndex(lit));
103 | }
104 |
105 | public void emitPUSHCONSTANT(final MethodGenerationContext mgenc, final byte literalIndex) {
106 | emit2(mgenc, PUSH_CONSTANT, literalIndex);
107 | }
108 |
109 | private void emit1(final MethodGenerationContext mgenc, final byte code) {
110 | mgenc.addBytecode(code);
111 | }
112 |
113 | private void emit2(final MethodGenerationContext mgenc, final byte code, final byte idx) {
114 | mgenc.addBytecode(code);
115 | mgenc.addBytecode(idx);
116 | }
117 |
118 | private void emit3(final MethodGenerationContext mgenc, final byte code, final byte idx,
119 | final byte ctx) {
120 | mgenc.addBytecode(code);
121 | mgenc.addBytecode(idx);
122 | mgenc.addBytecode(ctx);
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/src/som/compiler/ClassGenerationContext.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2013 Stefan Marr, stefan.marr@vub.ac.be
3 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
4 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
5 | * http://www.hpi.uni-potsdam.de/swa/
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 | package som.compiler;
26 |
27 | import java.util.ArrayList;
28 | import java.util.List;
29 |
30 | import som.vm.Universe;
31 | import som.vmobjects.SArray;
32 | import som.vmobjects.SClass;
33 | import som.vmobjects.SInvokable;
34 | import som.vmobjects.SSymbol;
35 |
36 |
37 | public class ClassGenerationContext {
38 |
39 | private final Universe universe;
40 |
41 | public ClassGenerationContext(final Universe universe) {
42 | this.universe = universe;
43 | }
44 |
45 | private SSymbol name;
46 | private SSymbol superName;
47 | private boolean classSide;
48 | private final List instanceFields = new ArrayList();
49 | private final List instanceMethods = new ArrayList();
50 | private final List classFields = new ArrayList();
51 | private final List classMethods = new ArrayList();
52 |
53 | public SSymbol getName() {
54 | return name;
55 | }
56 |
57 | public void setName(final SSymbol name) {
58 | this.name = name;
59 | }
60 |
61 | public void setSuperName(final SSymbol superName) {
62 | this.superName = superName;
63 | }
64 |
65 | public void setInstanceFieldsOfSuper(final SArray fieldNames) {
66 | int numFields = fieldNames.getNumberOfIndexableFields();
67 | for (int i = 0; i < numFields; i++) {
68 | instanceFields.add((SSymbol) fieldNames.getIndexableField(i));
69 | }
70 | }
71 |
72 | public void setClassFieldsOfSuper(final SArray fieldNames) {
73 | int numFields = fieldNames.getNumberOfIndexableFields();
74 | for (int i = 0; i < numFields; i++) {
75 | classFields.add((SSymbol) fieldNames.getIndexableField(i));
76 | }
77 | }
78 |
79 | public void addMethod(final som.vmobjects.SInvokable meth) {
80 | if (classSide) {
81 | classMethods.add(meth);
82 | } else {
83 | instanceMethods.add(meth);
84 | }
85 | }
86 |
87 | public void startClassSide() {
88 | classSide = true;
89 | }
90 |
91 | public void addField(final SSymbol field) {
92 | if (classSide) {
93 | classFields.add(field);
94 | } else {
95 | instanceFields.add(field);
96 | }
97 | }
98 |
99 | public boolean hasField(final SSymbol field) {
100 | return (isClassSide() ? classFields : instanceFields).contains(field);
101 | }
102 |
103 | public byte getFieldIndex(final SSymbol field) {
104 | if (isClassSide()) {
105 | return (byte) classFields.indexOf(field);
106 | } else {
107 | return (byte) instanceFields.indexOf(field);
108 | }
109 | }
110 |
111 | public boolean isClassSide() {
112 | return classSide;
113 | }
114 |
115 | public SClass assemble() throws ProgramDefinitionError {
116 | // build class class name
117 | String ccname = name.getEmbeddedString() + " class";
118 |
119 | // Load the super class
120 | SClass superClass = universe.loadClass(superName);
121 |
122 | // Allocate the class of the resulting class
123 | SClass resultClass = universe.newClass(universe.metaclassClass);
124 |
125 | // Initialize the class of the resulting class
126 | resultClass.setInstanceFields(universe.newArray(classFields));
127 | resultClass.setInstanceInvokables(universe.newArray(classMethods));
128 | resultClass.setName(universe.symbolFor(ccname));
129 |
130 | SClass superMClass = superClass.getSOMClass();
131 | resultClass.setSuperClass(superMClass);
132 |
133 | // Allocate the resulting class
134 | SClass result = universe.newClass(resultClass);
135 |
136 | // Initialize the resulting class
137 | result.setName(name);
138 | result.setSuperClass(superClass);
139 | result.setInstanceFields(universe.newArray(instanceFields));
140 | result.setInstanceInvokables(universe.newArray(instanceMethods));
141 |
142 | return result;
143 | }
144 |
145 | public SClass assembleSystemClass(final SClass systemClass) {
146 | systemClass.setInstanceInvokables(universe.newArray(instanceMethods));
147 | systemClass.setInstanceFields(universe.newArray(instanceFields));
148 | // class-bound == class-instance-bound
149 | SClass superMClass = systemClass.getSOMClass();
150 | superMClass.setInstanceInvokables(universe.newArray(classMethods));
151 | superMClass.setInstanceFields(universe.newArray(classFields));
152 | return systemClass;
153 | }
154 |
155 | }
156 |
--------------------------------------------------------------------------------
/src/som/compiler/Disassembler.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Michael Haupt, github@haupz.de
3 | * Copyright (c) 2013 Stefan Marr, stefan.marr@vub.ac.be
4 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
5 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
6 | * http://www.hpi.uni-potsdam.de/swa/
7 | *
8 | * Permission is hereby granted, free of charge, to any person obtaining a copy
9 | * of this software and associated documentation files (the "Software"), to deal
10 | * in the Software without restriction, including without limitation the rights
11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | * copies of the Software, and to permit persons to whom the Software is
13 | * furnished to do so, subject to the following conditions:
14 | *
15 | * The above copyright notice and this permission notice shall be included in
16 | * all copies or substantial portions of the Software.
17 | *
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | * THE SOFTWARE.
25 | */
26 |
27 | package som.compiler;
28 |
29 | import static som.interpreter.Bytecodes.POP_ARGUMENT;
30 | import static som.interpreter.Bytecodes.POP_FIELD;
31 | import static som.interpreter.Bytecodes.POP_LOCAL;
32 | import static som.interpreter.Bytecodes.PUSH_ARGUMENT;
33 | import static som.interpreter.Bytecodes.PUSH_BLOCK;
34 | import static som.interpreter.Bytecodes.PUSH_CONSTANT;
35 | import static som.interpreter.Bytecodes.PUSH_FIELD;
36 | import static som.interpreter.Bytecodes.PUSH_GLOBAL;
37 | import static som.interpreter.Bytecodes.PUSH_LOCAL;
38 | import static som.interpreter.Bytecodes.SEND;
39 | import static som.interpreter.Bytecodes.SUPER_SEND;
40 | import static som.interpreter.Bytecodes.getBytecodeLength;
41 | import static som.interpreter.Bytecodes.getPaddedBytecodeName;
42 |
43 | import som.vm.Universe;
44 | import som.vmobjects.SAbstractObject;
45 | import som.vmobjects.SClass;
46 | import som.vmobjects.SInvokable;
47 | import som.vmobjects.SMethod;
48 | import som.vmobjects.SSymbol;
49 |
50 |
51 | public class Disassembler {
52 |
53 | public static void dump(final SClass cl, final Universe universe) {
54 | for (int i = 0; i < cl.getNumberOfInstanceInvokables(); i++) {
55 | SInvokable inv = cl.getInstanceInvokable(i);
56 |
57 | // output header and skip if the Invokable is a Primitive
58 | Universe.errorPrint(cl.getName().toString() + ">>"
59 | + inv.getSignature().toString() + " = ");
60 |
61 | if (inv.isPrimitive()) {
62 | Universe.errorPrintln("");
63 | continue;
64 | }
65 | // output actual method
66 | dumpMethod((SMethod) inv, "\t", universe);
67 | }
68 | }
69 |
70 | public static void dumpMethod(final SMethod m, final String indent,
71 | final Universe universe) {
72 | Universe.errorPrintln("(");
73 |
74 | // output stack information
75 | Universe.errorPrintln(indent + "<" + m.getNumberOfLocals() + " locals, "
76 | + m.getMaximumNumberOfStackElements() + " stack, "
77 | + m.getNumberOfBytecodes() + " bc_count>");
78 |
79 | // output bytecodes
80 | for (int b = 0; b < m.getNumberOfBytecodes(); b +=
81 | getBytecodeLength(m.getBytecode(b))) {
82 |
83 | Universe.errorPrint(indent);
84 |
85 | // bytecode index
86 | if (b < 10) {
87 | Universe.errorPrint(" ");
88 | }
89 | if (b < 100) {
90 | Universe.errorPrint(" ");
91 | }
92 | Universe.errorPrint(" " + b + ":");
93 |
94 | // mnemonic
95 | byte bytecode = m.getBytecode(b);
96 | Universe.errorPrint(getPaddedBytecodeName(bytecode) + " ");
97 |
98 | // parameters (if any)
99 | if (getBytecodeLength(bytecode) == 1) {
100 | Universe.errorPrintln();
101 | continue;
102 | }
103 | switch (bytecode) {
104 | case PUSH_LOCAL:
105 | Universe.errorPrintln("local: " + m.getBytecode(b + 1) + ", context: "
106 | + m.getBytecode(b + 2));
107 | break;
108 | case PUSH_ARGUMENT:
109 | Universe.errorPrintln("argument: " + m.getBytecode(b + 1) + ", context "
110 | + m.getBytecode(b + 2));
111 | break;
112 | case PUSH_FIELD: {
113 | int idx = m.getBytecode(b + 1);
114 | String fieldName = ((SSymbol) m.getHolder().getInstanceFields()
115 | .getIndexableField(idx)).getEmbeddedString();
116 | Universe.errorPrintln("(index: " + idx + ") field: " + fieldName);
117 | break;
118 | }
119 | case PUSH_BLOCK:
120 | Universe.errorPrint("block: (index: " + m.getBytecode(b + 1) + ") ");
121 | dumpMethod((SMethod) m.getConstant(b), indent + "\t", universe);
122 | break;
123 | case PUSH_CONSTANT:
124 | SAbstractObject constant = m.getConstant(b);
125 | Universe.errorPrintln("(index: " + m.getBytecode(b + 1) + ") value: "
126 | + "(" + constant.getSOMClass(universe).getName().toString() + ") "
127 | + constant.toString());
128 | break;
129 | case PUSH_GLOBAL:
130 | Universe.errorPrintln("(index: " + m.getBytecode(b + 1) + ") value: "
131 | + ((SSymbol) m.getConstant(b)).toString());
132 | break;
133 | case POP_LOCAL:
134 | Universe.errorPrintln("local: " + m.getBytecode(b + 1) + ", context: "
135 | + m.getBytecode(b + 2));
136 | break;
137 | case POP_ARGUMENT:
138 | Universe.errorPrintln("argument: " + m.getBytecode(b + 1)
139 | + ", context: " + m.getBytecode(b + 2));
140 | break;
141 | case POP_FIELD: {
142 | int idx = m.getBytecode(b + 1);
143 | String fieldName = ((SSymbol) m.getHolder().getInstanceFields()
144 | .getIndexableField(idx)).getEmbeddedString();
145 | Universe.errorPrintln("(index: " + idx + ") field: " + fieldName);
146 | break;
147 | }
148 | case SEND:
149 | Universe.errorPrintln("(index: " + m.getBytecode(b + 1)
150 | + ") signature: " + ((SSymbol) m.getConstant(b)).toString());
151 | break;
152 | case SUPER_SEND:
153 | Universe.errorPrintln("(index: " + m.getBytecode(b + 1)
154 | + ") signature: " + ((SSymbol) m.getConstant(b)).toString());
155 | break;
156 | default:
157 | Universe.errorPrintln("");
158 | }
159 | }
160 | Universe.errorPrintln(indent + ")");
161 | }
162 |
163 | }
164 |
--------------------------------------------------------------------------------
/src/som/compiler/MethodGenerationContext.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Michael Haupt, github@haupz.de
3 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
4 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
5 | * http://www.hpi.uni-potsdam.de/swa/
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package som.compiler;
27 |
28 | import static som.interpreter.Bytecodes.DUP;
29 | import static som.interpreter.Bytecodes.HALT;
30 | import static som.interpreter.Bytecodes.POP;
31 | import static som.interpreter.Bytecodes.POP_ARGUMENT;
32 | import static som.interpreter.Bytecodes.POP_FIELD;
33 | import static som.interpreter.Bytecodes.POP_LOCAL;
34 | import static som.interpreter.Bytecodes.PUSH_ARGUMENT;
35 | import static som.interpreter.Bytecodes.PUSH_BLOCK;
36 | import static som.interpreter.Bytecodes.PUSH_CONSTANT;
37 | import static som.interpreter.Bytecodes.PUSH_FIELD;
38 | import static som.interpreter.Bytecodes.PUSH_GLOBAL;
39 | import static som.interpreter.Bytecodes.PUSH_LOCAL;
40 | import static som.interpreter.Bytecodes.RETURN_LOCAL;
41 | import static som.interpreter.Bytecodes.RETURN_NON_LOCAL;
42 | import static som.interpreter.Bytecodes.SEND;
43 | import static som.interpreter.Bytecodes.SUPER_SEND;
44 |
45 | import java.util.ArrayList;
46 | import java.util.List;
47 |
48 | import som.compiler.Parser.ParseError;
49 | import som.vm.Universe;
50 | import som.vmobjects.SAbstractObject;
51 | import som.vmobjects.SInvokable;
52 | import som.vmobjects.SMethod;
53 | import som.vmobjects.SPrimitive;
54 | import som.vmobjects.SSymbol;
55 |
56 |
57 | public class MethodGenerationContext {
58 |
59 | private final ClassGenerationContext holderGenc;
60 | private final MethodGenerationContext outerGenc;
61 | private final boolean blockMethod;
62 |
63 | private SSymbol signature;
64 | private final List arguments = new ArrayList();
65 | private boolean primitive;
66 | private final List locals = new ArrayList();
67 | private final List literals = new ArrayList();
68 | private boolean finished;
69 | private final ArrayList bytecode = new ArrayList<>();
70 |
71 | /**
72 | * Constructor used for block methods.
73 | */
74 | public MethodGenerationContext(final ClassGenerationContext holderGenc,
75 | final MethodGenerationContext outerGenc) {
76 | this.holderGenc = holderGenc;
77 | this.outerGenc = outerGenc;
78 | blockMethod = outerGenc != null;
79 | }
80 |
81 | /**
82 | * Constructor used for normal methods.
83 | */
84 | public MethodGenerationContext(final ClassGenerationContext holderGenc) {
85 | this(holderGenc, null);
86 | }
87 |
88 | public void addArgument(final String arg) {
89 | arguments.add(arg);
90 | }
91 |
92 | public boolean isPrimitive() {
93 | return primitive;
94 | }
95 |
96 | public SInvokable assemble(final Universe universe) {
97 | if (primitive) {
98 | return SPrimitive.getEmptyPrimitive(signature.getEmbeddedString(), universe);
99 | } else {
100 | return assembleMethod(universe);
101 | }
102 | }
103 |
104 | public SMethod assembleMethod(final Universe universe) {
105 | // create a method instance with the given number of bytecodes
106 | int numLocals = locals.size();
107 |
108 | SMethod meth = universe.newMethod(signature, bytecode.size(),
109 | numLocals, computeStackDepth(),
110 | literals);
111 |
112 | // copy bytecodes into method
113 | int i = 0;
114 | for (byte bc : bytecode) {
115 | meth.setBytecode(i++, bc);
116 | }
117 |
118 | // return the method - the holder field is to be set later on!
119 | return meth;
120 | }
121 |
122 | private int computeStackDepth() {
123 | int depth = 0;
124 | int maxDepth = 0;
125 | int i = 0;
126 |
127 | while (i < bytecode.size()) {
128 | switch (bytecode.get(i)) {
129 | case HALT:
130 | i++;
131 | break;
132 | case DUP:
133 | depth++;
134 | i++;
135 | break;
136 | case PUSH_LOCAL:
137 | case PUSH_ARGUMENT:
138 | depth++;
139 | i += 3;
140 | break;
141 | case PUSH_FIELD:
142 | case PUSH_BLOCK:
143 | case PUSH_CONSTANT:
144 | case PUSH_GLOBAL:
145 | depth++;
146 | i += 2;
147 | break;
148 | case POP:
149 | depth--;
150 | i++;
151 | break;
152 | case POP_LOCAL:
153 | case POP_ARGUMENT:
154 | depth--;
155 | i += 3;
156 | break;
157 | case POP_FIELD:
158 | depth--;
159 | i += 2;
160 | break;
161 | case SEND:
162 | case SUPER_SEND: {
163 | // these are special: they need to look at the number of
164 | // arguments (extractable from the signature)
165 | SSymbol sig = (SSymbol) literals.get(bytecode.get(i + 1));
166 |
167 | depth -= sig.getNumberOfSignatureArguments();
168 |
169 | depth++; // return value
170 | i += 2;
171 | break;
172 | }
173 | case RETURN_LOCAL:
174 | case RETURN_NON_LOCAL:
175 | i++;
176 | break;
177 | default:
178 | throw new IllegalStateException("Illegal bytecode "
179 | + bytecode.get(i));
180 | }
181 |
182 | if (depth > maxDepth) {
183 | maxDepth = depth;
184 | }
185 | }
186 |
187 | return maxDepth;
188 | }
189 |
190 | public void markAsPrimitive() {
191 | primitive = true;
192 | }
193 |
194 | public void setSignature(final SSymbol sig) {
195 | signature = sig;
196 | }
197 |
198 | public boolean addArgumentIfAbsent(final String arg) {
199 | if (arguments.contains(arg)) {
200 | return false;
201 | }
202 |
203 | arguments.add(arg);
204 | return true;
205 | }
206 |
207 | public boolean isFinished() {
208 | return finished;
209 | }
210 |
211 | public void markAsFinished() {
212 | this.finished = false;
213 | }
214 |
215 | public boolean addLocalIfAbsent(final String local) {
216 | if (locals.contains(local)) {
217 | return false;
218 | }
219 |
220 | locals.add(local);
221 | return true;
222 | }
223 |
224 | public void addLocal(final String local) {
225 | locals.add(local);
226 | }
227 |
228 | public boolean hasBytecodes() {
229 | return !bytecode.isEmpty();
230 | }
231 |
232 | public void removeLastBytecode() {
233 | bytecode.remove(bytecode.size() - 1);
234 | }
235 |
236 | public boolean isBlockMethod() {
237 | return blockMethod;
238 | }
239 |
240 | public void setFinished() {
241 | finished = true;
242 | }
243 |
244 | public boolean addLiteralIfAbsent(final SAbstractObject lit, final Parser parser)
245 | throws ParseError {
246 | if (literals.contains(lit)) {
247 | return false;
248 | }
249 |
250 | addLiteral(lit, parser);
251 | return true;
252 | }
253 |
254 | public ClassGenerationContext getHolder() {
255 | return holderGenc;
256 | }
257 |
258 | public byte addLiteral(final SAbstractObject lit, final Parser parser) throws ParseError {
259 | int i = literals.size();
260 | if (i > Byte.MAX_VALUE) {
261 | String methodSignature = holderGenc.getName().getEmbeddedString() + ">>" + signature;
262 | throw new ParseError(
263 | "The method " + methodSignature + " has more than the supported " +
264 | Byte.MAX_VALUE
265 | + " literal values. Please split the method. The literal to be added is: " + lit,
266 | Symbol.NONE, parser);
267 | }
268 | literals.add(lit);
269 | return (byte) i;
270 | }
271 |
272 | public void updateLiteral(final SAbstractObject oldVal, final byte index,
273 | final SAbstractObject newVal) {
274 | assert literals.get(index) == oldVal;
275 | literals.set(index, newVal);
276 | }
277 |
278 | public boolean findVar(final String var, final Triplet tri) {
279 | // triplet: index, context, isArgument
280 | tri.setX((byte) locals.indexOf(var));
281 | if (tri.getX() == -1) {
282 | tri.setX((byte) arguments.indexOf(var));
283 | if (tri.getX() == -1) {
284 | if (outerGenc == null) {
285 | return false;
286 | } else {
287 | tri.setY((byte) (tri.getY() + 1));
288 | return outerGenc.findVar(var, tri);
289 | }
290 | } else {
291 | tri.setZ(true);
292 | }
293 | }
294 |
295 | return true;
296 | }
297 |
298 | public boolean hasField(final SSymbol field) {
299 | return holderGenc.hasField(field);
300 | }
301 |
302 | public byte getFieldIndex(final SSymbol field) {
303 | return holderGenc.getFieldIndex(field);
304 | }
305 |
306 | public int getNumberOfArguments() {
307 | return arguments.size();
308 | }
309 |
310 | public void addBytecode(final byte code) {
311 | bytecode.add(code);
312 | }
313 |
314 | public byte findLiteralIndex(final SAbstractObject lit) {
315 | return (byte) literals.indexOf(lit);
316 | }
317 |
318 | public MethodGenerationContext getOuter() {
319 | return outerGenc;
320 | }
321 | }
322 |
--------------------------------------------------------------------------------
/src/som/compiler/ProgramDefinitionError.java:
--------------------------------------------------------------------------------
1 | package som.compiler;
2 |
3 | public class ProgramDefinitionError extends Exception {
4 | private static final long serialVersionUID = -2555195397219550779L;
5 |
6 | public ProgramDefinitionError(final String message) {
7 | super(message);
8 | }
9 |
10 | @Override
11 | public String toString() {
12 | return "ProgramDefinitionError: " + getMessage();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/som/compiler/SourcecodeCompiler.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.compiler;
26 |
27 | import java.io.FileReader;
28 | import java.io.IOException;
29 | import java.io.StringReader;
30 |
31 | import som.vm.Universe;
32 | import som.vmobjects.SClass;
33 | import som.vmobjects.SSymbol;
34 |
35 |
36 | public class SourcecodeCompiler {
37 |
38 | private Parser parser;
39 |
40 | public static SClass compileClass(final String path, final String file,
41 | final SClass systemClass, final Universe universe)
42 | throws IOException, ProgramDefinitionError {
43 | return new SourcecodeCompiler().compile(path, file, systemClass, universe);
44 | }
45 |
46 | public static SClass compileClass(final String stmt, final SClass systemClass,
47 | final Universe universe) throws ProgramDefinitionError {
48 | return new SourcecodeCompiler().compileClassString(stmt, systemClass,
49 | universe);
50 | }
51 |
52 | private SClass compile(final String path, final String file,
53 | final SClass systemClass, final Universe universe)
54 | throws IOException, ProgramDefinitionError {
55 | String fname = path + Universe.fileSeparator + file + ".som";
56 |
57 | parser = new Parser(new FileReader(fname), universe, fname);
58 |
59 | SClass result = compile(systemClass);
60 |
61 | SSymbol cname = result.getName();
62 | String cnameC = cname.getEmbeddedString();
63 |
64 | if (file != cnameC) {
65 | throw new ProgramDefinitionError("File name " + fname
66 | + " does not match class name (" + cnameC + ") in it.");
67 | }
68 |
69 | return result;
70 | }
71 |
72 | private SClass compileClassString(final String stream,
73 | final SClass systemClass, final Universe universe)
74 | throws ProgramDefinitionError {
75 | parser = new Parser(new StringReader(stream), universe, "$string$");
76 |
77 | SClass result = compile(systemClass);
78 | return result;
79 | }
80 |
81 | private SClass compile(final SClass systemClass) throws ProgramDefinitionError {
82 | ClassGenerationContext cgc = parser.classdef();
83 |
84 | if (systemClass == null) {
85 | return cgc.assemble();
86 | } else {
87 | return cgc.assembleSystemClass(systemClass);
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/som/compiler/Symbol.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.compiler;
26 |
27 | enum Symbol {
28 | NONE, Integer, Double, Not, And, Or, Star, Div, Mod, Plus, Minus, Equal, More,
29 | Less, Comma, At, Per, NewBlock, EndBlock, Colon, Period, Exit, Assign, NewTerm,
30 | EndTerm, Pound, Primitive, Separator, STString, Identifier, Keyword,
31 | KeywordSequence, OperatorSequence
32 | }
33 |
--------------------------------------------------------------------------------
/src/som/compiler/Triplet.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.compiler;
26 |
27 | public class Triplet {
28 |
29 | X x;
30 | Y y;
31 | Z z;
32 |
33 | public Triplet(X x, Y y, Z z) {
34 | setX(x);
35 | setY(y);
36 | setZ(z);
37 | }
38 |
39 | public void setX(X x) {
40 | this.x = x;
41 | }
42 |
43 | public void setY(Y y) {
44 | this.y = y;
45 | }
46 |
47 | public void setZ(Z z) {
48 | this.z = z;
49 | }
50 |
51 | public X getX() {
52 | return x;
53 | }
54 |
55 | public Y getY() {
56 | return y;
57 | }
58 |
59 | public Z getZ() {
60 | return z;
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/src/som/interpreter/Bytecodes.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Michael Haupt, github@haupz.de
3 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
4 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
5 | * http://www.hpi.uni-potsdam.de/swa/
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package som.interpreter;
27 |
28 | import java.util.stream.Stream;
29 |
30 |
31 | public class Bytecodes {
32 |
33 | // Bytecodes used by the simple object machine
34 | public static final byte HALT = 0;
35 | public static final byte DUP = 1;
36 | public static final byte PUSH_LOCAL = 2;
37 | public static final byte PUSH_ARGUMENT = 3;
38 | public static final byte PUSH_FIELD = 4;
39 | public static final byte PUSH_BLOCK = 5;
40 | public static final byte PUSH_CONSTANT = 6;
41 | public static final byte PUSH_GLOBAL = 7;
42 | public static final byte POP = 8;
43 | public static final byte POP_LOCAL = 9;
44 | public static final byte POP_ARGUMENT = 10;
45 | public static final byte POP_FIELD = 11;
46 | public static final byte SEND = 12;
47 | public static final byte SUPER_SEND = 13;
48 | public static final byte RETURN_LOCAL = 14;
49 | public static final byte RETURN_NON_LOCAL = 15;
50 |
51 | private static final String[] PADDED_BYTECODE_NAMES = new String[] {
52 | "HALT ", "DUP ", "PUSH_LOCAL ",
53 | "PUSH_ARGUMENT ", "PUSH_FIELD ", "PUSH_BLOCK ",
54 | "PUSH_CONSTANT ", "PUSH_GLOBAL ", "POP ",
55 | "POP_LOCAL ", "POP_ARGUMENT ", "POP_FIELD ",
56 | "SEND ", "SUPER_SEND ", "RETURN_LOCAL ",
57 | "RETURN_NON_LOCAL"
58 | };
59 |
60 | private static final String[] BYTECODE_NAMES =
61 | Stream.of(PADDED_BYTECODE_NAMES).map(String::trim).toArray(String[]::new);
62 |
63 | private static final byte NUM_BYTECODES = (byte) BYTECODE_NAMES.length;
64 |
65 | private static void checkBytecodeIndex(byte bytecode) {
66 | if (bytecode < 0 || bytecode >= NUM_BYTECODES) {
67 | throw new IllegalArgumentException("illegal bytecode: " + bytecode);
68 | }
69 | }
70 |
71 | public static String getBytecodeName(byte bytecode) {
72 | checkBytecodeIndex(bytecode);
73 | return BYTECODE_NAMES[bytecode];
74 | }
75 |
76 | public static String getPaddedBytecodeName(byte bytecode) {
77 | checkBytecodeIndex(bytecode);
78 | return PADDED_BYTECODE_NAMES[bytecode];
79 | }
80 |
81 | public static int getBytecodeLength(byte bytecode) {
82 | // Return the length of the given bytecode
83 | return BYTECODE_LENGTH[bytecode];
84 | }
85 |
86 | // Static array holding lengths of each bytecode
87 | private static final int[] BYTECODE_LENGTH = new int[] {
88 | 1, // HALT
89 | 1, // DUP
90 | 3, // PUSH_LOCAL
91 | 3, // PUSH_ARGUMENT
92 | 2, // PUSH_FIELD
93 | 2, // PUSH_BLOCK
94 | 2, // PUSH_CONSTANT
95 | 2, // PUSH_GLOBAL
96 | 1, // POP
97 | 3, // POP_LOCAL
98 | 3, // POP_ARGUMENT
99 | 2, // POP_FIELD
100 | 2, // SEND
101 | 2, // SUPER_SEND
102 | 1, // RETURN_LOCAL
103 | 1 // RETURN_NON_LOCAL
104 | };
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/src/som/interpreter/Frame.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.interpreter;
26 |
27 | import som.vm.Universe;
28 | import som.vmobjects.SAbstractObject;
29 | import som.vmobjects.SMethod;
30 | import som.vmobjects.SObject;
31 |
32 |
33 | /**
34 | * @formatter:off
35 | * Frame layout:
36 | *
37 | * +-----------------+
38 | * | Arguments | 0
39 | * +-----------------+
40 | * | Local Variables | <-- localOffset
41 | * +-----------------+
42 | * | Stack | <-- stackPointer
43 | * | ... |
44 | * +-----------------+
45 | * @formatter:on
46 | */
47 | public class Frame {
48 |
49 | public Frame(final SObject nilObject, final Frame previousFrame,
50 | final Frame context, final SMethod method, final long stackElements) {
51 | this.previousFrame = previousFrame;
52 | this.context = context;
53 | this.method = method;
54 | this.stack = new SAbstractObject[(int) stackElements];
55 |
56 | for (int i = 0; i < stackElements; i++) {
57 | stack[i] = nilObject;
58 | }
59 |
60 | // Reset the stack pointer and the bytecode index
61 | resetStackPointer();
62 | bytecodeIndex = 0;
63 | }
64 |
65 | public Frame getPreviousFrame() {
66 | return previousFrame;
67 | }
68 |
69 | public void clearPreviousFrame() {
70 | previousFrame = null;
71 | }
72 |
73 | public boolean hasPreviousFrame() {
74 | return previousFrame != null;
75 | }
76 |
77 | public boolean isBootstrapFrame() {
78 | return !hasPreviousFrame();
79 | }
80 |
81 | public Frame getContext() {
82 | return context;
83 | }
84 |
85 | public boolean hasContext() {
86 | return context != null;
87 | }
88 |
89 | public Frame getContext(int level) {
90 | // Get the context frame at the given level
91 | Frame frame = this;
92 |
93 | // Iterate through the context chain until the given level is reached
94 | while (level > 0) {
95 | // Get the context of the current frame
96 | frame = frame.getContext();
97 |
98 | // Go to the next level
99 | level = level - 1;
100 | }
101 |
102 | // Return the found context
103 | return frame;
104 | }
105 |
106 | public Frame getOuterContext() {
107 | // Compute the outer context of this frame
108 | Frame frame = this;
109 |
110 | // Iterate through the context chain until null is reached
111 | while (frame.hasContext()) {
112 | frame = frame.getContext();
113 | }
114 |
115 | // Return the outer context
116 | return frame;
117 | }
118 |
119 | public SMethod getMethod() {
120 | return method;
121 | }
122 |
123 | public SAbstractObject pop() {
124 | // Pop an object from the expression stack and return it
125 | int sp = stackPointer;
126 | stackPointer -= 1;
127 | return stack[sp];
128 | }
129 |
130 | public void push(final SAbstractObject value) {
131 | // Push an object onto the expression stack
132 | int sp = stackPointer + 1;
133 | stack[sp] = value;
134 | stackPointer = sp;
135 | }
136 |
137 | public void resetStackPointer() {
138 | // arguments are stored in front of local variables
139 | localOffset = getMethod().getNumberOfArguments();
140 |
141 | // Set the stack pointer to its initial value thereby clearing the stack
142 | stackPointer = localOffset + getMethod().getNumberOfLocals() - 1;
143 | }
144 |
145 | public int getBytecodeIndex() {
146 | // Get the current bytecode index for this frame
147 | return bytecodeIndex;
148 | }
149 |
150 | public void setBytecodeIndex(final int value) {
151 | // Set the current bytecode index for this frame
152 | bytecodeIndex = value;
153 | }
154 |
155 | public SAbstractObject getStackElement(final int index) {
156 | // Get the stack element with the given index
157 | // (an index of zero yields the top element)
158 | return stack[stackPointer - index];
159 | }
160 |
161 | public void setStackElement(final int index, final SAbstractObject value) {
162 | // Set the stack element with the given index to the given value
163 | // (an index of zero yields the top element)
164 | stack[stackPointer - index] = value;
165 | }
166 |
167 | private SAbstractObject getLocal(final int index) {
168 | return stack[localOffset + index];
169 | }
170 |
171 | private void setLocal(final int index, final SAbstractObject value) {
172 | stack[localOffset + index] = value;
173 | }
174 |
175 | public SAbstractObject getLocal(final int index, final int contextLevel) {
176 | // Get the local with the given index in the given context
177 | return getContext(contextLevel).getLocal(index);
178 | }
179 |
180 | public void setLocal(final int index, final int contextLevel, final SAbstractObject value) {
181 | // Set the local with the given index in the given context to the given
182 | // value
183 | getContext(contextLevel).setLocal(index, value);
184 | }
185 |
186 | public SAbstractObject getArgument(final int index, final int contextLevel) {
187 | // Get the context
188 | Frame context = getContext(contextLevel);
189 |
190 | // Get the argument with the given index
191 | return context.stack[index];
192 | }
193 |
194 | public void setArgument(final int index, final int contextLevel,
195 | final SAbstractObject value) {
196 | // Get the context
197 | Frame context = getContext(contextLevel);
198 |
199 | // Set the argument with the given index to the given value
200 | context.stack[index] = value;
201 | }
202 |
203 | public void copyArgumentsFrom(final Frame frame) {
204 | // copy arguments from frame:
205 | // - arguments are at the top of the stack of frame.
206 | // - copy them into the argument area of the current frame
207 | int numArgs = getMethod().getNumberOfArguments();
208 | for (int i = 0; i < numArgs; ++i) {
209 | stack[i] = frame.getStackElement(numArgs - 1 - i);
210 | }
211 | }
212 |
213 | public void printStackTrace() {
214 | // Print a stack trace starting in this frame
215 | if (hasPreviousFrame()) {
216 | getPreviousFrame().printStackTrace();
217 | }
218 |
219 | String className = getMethod().getHolder().getName().getEmbeddedString();
220 | String methodName = getMethod().getSignature().getEmbeddedString();
221 | Universe.println(className + ">>#" + methodName + " @bi: " + bytecodeIndex);
222 | }
223 |
224 | // Private variables holding the stack pointer and the bytecode index
225 | private int stackPointer;
226 | private int bytecodeIndex;
227 |
228 | // the offset at which local variables start
229 | private int localOffset;
230 |
231 | private final SMethod method;
232 | private final Frame context;
233 | private Frame previousFrame;
234 | private final SAbstractObject[] stack;
235 | }
236 |
--------------------------------------------------------------------------------
/src/som/primitives/ArrayPrimitives.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.primitives;
26 |
27 | import som.vm.Universe;
28 | import som.vmobjects.SArray;
29 | import som.vmobjects.SInteger;
30 | import som.vmobjects.SAbstractObject;
31 | import som.vmobjects.SPrimitive;
32 | import som.interpreter.Interpreter;
33 | import som.interpreter.Frame;
34 |
35 |
36 | public class ArrayPrimitives extends Primitives {
37 |
38 | public ArrayPrimitives(final Universe universe) {
39 | super(universe);
40 | }
41 |
42 | public void installPrimitives() {
43 | installInstancePrimitive(new SPrimitive("at:", universe) {
44 |
45 | public void invoke(final Frame frame, final Interpreter interpreter) {
46 | SInteger index = (SInteger) frame.pop();
47 | SArray self = (SArray) frame.pop();
48 | frame.push(self.getIndexableField(index.getEmbeddedInteger() - 1));
49 | }
50 | });
51 |
52 | installInstancePrimitive(new SPrimitive("at:put:", universe) {
53 |
54 | public void invoke(final Frame frame, final Interpreter interpreter) {
55 | SAbstractObject value = frame.pop();
56 | SInteger index = (SInteger) frame.pop();
57 | SArray self = (SArray) frame.getStackElement(0);
58 | self.setIndexableField(index.getEmbeddedInteger() - 1, value);
59 | }
60 | });
61 |
62 | installInstancePrimitive(new SPrimitive("length", universe) {
63 |
64 | public void invoke(final Frame frame, final Interpreter interpreter) {
65 | SArray self = (SArray) frame.pop();
66 | frame.push(universe.newInteger(self.getNumberOfIndexableFields()));
67 | }
68 | });
69 |
70 | installClassPrimitive(new SPrimitive("new:", universe) {
71 |
72 | public void invoke(final Frame frame, final Interpreter interpreter) {
73 | SInteger length = (SInteger) frame.pop();
74 | frame.pop(); // not required
75 | frame.push(universe.newArray(length.getEmbeddedInteger()));
76 | }
77 | });
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/som/primitives/BlockPrimitives.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.primitives;
26 |
27 | import som.vm.Universe;
28 | import som.interpreter.Interpreter;
29 | import som.interpreter.Frame;
30 | import som.vmobjects.SPrimitive;
31 |
32 |
33 | public class BlockPrimitives extends Primitives {
34 |
35 | public BlockPrimitives(final Universe universe) {
36 | super(universe);
37 | }
38 |
39 | public void installPrimitives() {
40 | installInstancePrimitive(new SPrimitive("restart", universe) {
41 |
42 | public void invoke(final Frame frame, final Interpreter interpreter) {
43 | frame.setBytecodeIndex(0);
44 | frame.resetStackPointer();
45 | }
46 | });
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/som/primitives/ClassPrimitives.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.primitives;
26 |
27 | import som.interpreter.Frame;
28 | import som.interpreter.Interpreter;
29 | import som.vm.Universe;
30 | import som.vmobjects.SClass;
31 | import som.vmobjects.SPrimitive;
32 |
33 |
34 | public class ClassPrimitives extends Primitives {
35 |
36 | public ClassPrimitives(final Universe universe) {
37 | super(universe);
38 | }
39 |
40 | @Override
41 | public void installPrimitives() {
42 | installInstancePrimitive(new SPrimitive("new", universe) {
43 |
44 | @Override
45 | public void invoke(final Frame frame, final Interpreter interpreter) {
46 | SClass self = (SClass) frame.pop();
47 | frame.push(universe.newInstance(self));
48 | }
49 | });
50 |
51 | installInstancePrimitive(new SPrimitive("name", universe) {
52 |
53 | @Override
54 | public void invoke(final Frame frame, final Interpreter interpreter) {
55 | SClass self = (SClass) frame.pop();
56 | frame.push(self.getName());
57 | }
58 | });
59 |
60 | installInstancePrimitive(new SPrimitive("superclass", universe) {
61 |
62 | @Override
63 | public void invoke(final Frame frame, final Interpreter interpreter) {
64 | SClass self = (SClass) frame.pop();
65 | frame.push(self.getSuperClass());
66 | }
67 | });
68 |
69 | installInstancePrimitive(new SPrimitive("fields", universe) {
70 |
71 | @Override
72 | public void invoke(final Frame frame, final Interpreter interpreter) {
73 | SClass self = (SClass) frame.pop();
74 | frame.push(self.getInstanceFields());
75 | }
76 | });
77 |
78 | installInstancePrimitive(new SPrimitive("methods", universe) {
79 |
80 | @Override
81 | public void invoke(final Frame frame, final Interpreter interpreter) {
82 | SClass self = (SClass) frame.pop();
83 | frame.push(self.getInstanceInvokables());
84 | }
85 | });
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/som/primitives/DoublePrimitives.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.primitives;
26 |
27 | import som.interpreter.Frame;
28 | import som.interpreter.Interpreter;
29 | import som.vm.Universe;
30 | import som.vmobjects.SAbstractObject;
31 | import som.vmobjects.SDouble;
32 | import som.vmobjects.SNumber;
33 | import som.vmobjects.SPrimitive;
34 | import som.vmobjects.SString;
35 |
36 |
37 | public class DoublePrimitives extends Primitives {
38 |
39 | public DoublePrimitives(final Universe universe) {
40 | super(universe);
41 | }
42 |
43 | @Override
44 | public void installPrimitives() {
45 | installInstancePrimitive(new SPrimitive("asString", universe) {
46 | @Override
47 | public void invoke(final Frame frame, final Interpreter interpreter) {
48 | SDouble self = (SDouble) frame.pop();
49 | frame.push(self.primAsString(universe));
50 | }
51 | });
52 |
53 | installInstancePrimitive(new SPrimitive("asInteger", universe) {
54 | @Override
55 | public void invoke(final Frame frame, final Interpreter interpreter) {
56 | SDouble self = (SDouble) frame.pop();
57 | frame.push(self.primAsInteger(universe));
58 | }
59 | });
60 |
61 | installInstancePrimitive(new SPrimitive("sqrt", universe) {
62 | @Override
63 | public void invoke(final Frame frame, final Interpreter interpreter) {
64 | SDouble self = (SDouble) frame.pop();
65 | frame.push(self.primSqrt(universe));
66 | }
67 | });
68 |
69 | installInstancePrimitive(new SPrimitive("+", universe) {
70 | @Override
71 | public void invoke(final Frame frame, final Interpreter interpreter) {
72 | SNumber op1 = (SNumber) frame.pop();
73 | SDouble op2 = (SDouble) frame.pop();
74 | frame.push(op2.primAdd(op1, universe));
75 | }
76 | });
77 |
78 | installInstancePrimitive(new SPrimitive("-", universe) {
79 | @Override
80 | public void invoke(final Frame frame, final Interpreter interpreter) {
81 | SNumber op1 = (SNumber) frame.pop();
82 | SDouble op2 = (SDouble) frame.pop();
83 | frame.push(op2.primSubtract(op1, universe));
84 | }
85 | });
86 |
87 | installInstancePrimitive(new SPrimitive("*", universe) {
88 | @Override
89 | public void invoke(final Frame frame, final Interpreter interpreter) {
90 | SNumber op1 = (SNumber) frame.pop();
91 | SDouble op2 = (SDouble) frame.pop();
92 | frame.push(op2.primMultiply(op1, universe));
93 | }
94 | });
95 |
96 | installInstancePrimitive(new SPrimitive("//", universe) {
97 | @Override
98 | public void invoke(final Frame frame, final Interpreter interpreter) {
99 | SNumber op1 = (SNumber) frame.pop();
100 | SDouble op2 = (SDouble) frame.pop();
101 | frame.push(op2.primDoubleDivide(op1, universe));
102 | }
103 | });
104 |
105 | installInstancePrimitive(new SPrimitive("%", universe) {
106 | @Override
107 | public void invoke(final Frame frame, final Interpreter interpreter) {
108 | SNumber op1 = (SNumber) frame.pop();
109 | SDouble op2 = (SDouble) frame.pop();
110 | frame.push(op2.primModulo(op1, universe));
111 | }
112 | });
113 |
114 | installInstancePrimitive(new SPrimitive("=", universe) {
115 | @Override
116 | public void invoke(final Frame frame, final Interpreter interpreter) {
117 | SAbstractObject op1 = frame.pop();
118 | SDouble op2 = (SDouble) frame.pop();
119 | frame.push(op2.primEqual(op1, universe));
120 | }
121 | });
122 |
123 | installInstancePrimitive(new SPrimitive("<", universe) {
124 | @Override
125 | public void invoke(final Frame frame, final Interpreter interpreter) {
126 | SNumber op1 = (SNumber) frame.pop();
127 | SDouble op2 = (SDouble) frame.pop();
128 | frame.push(op2.primLessThan(op1, universe));
129 | }
130 | });
131 |
132 | installInstancePrimitive(new SPrimitive("round", universe) {
133 | @Override
134 | public void invoke(final Frame frame, final Interpreter interpreter) {
135 | SDouble rcvr = (SDouble) frame.pop();
136 | long result = Math.round(rcvr.getEmbeddedDouble());
137 | frame.push(universe.newInteger(result));
138 | }
139 | });
140 |
141 | installInstancePrimitive(new SPrimitive("sin", universe) {
142 | @Override
143 | public void invoke(final Frame frame, final Interpreter interpreter) {
144 | SDouble rcvr = (SDouble) frame.pop();
145 | double result = Math.sin(rcvr.getEmbeddedDouble());
146 | frame.push(universe.newDouble(result));
147 | }
148 | });
149 |
150 | installInstancePrimitive(new SPrimitive("cos", universe) {
151 | @Override
152 | public void invoke(final Frame frame, final Interpreter interpreter) {
153 | SDouble rcvr = (SDouble) frame.pop();
154 | double result = Math.cos(rcvr.getEmbeddedDouble());
155 | frame.push(universe.newDouble(result));
156 | }
157 | });
158 |
159 | installClassPrimitive(new SPrimitive("PositiveInfinity", universe) {
160 | @Override
161 | public void invoke(final Frame frame, final Interpreter interpreter) {
162 | frame.pop();
163 | frame.push(universe.newDouble(Double.POSITIVE_INFINITY));
164 | }
165 | });
166 |
167 | installClassPrimitive(new SPrimitive("fromString:", universe) {
168 | @Override
169 | public void invoke(final Frame frame, final Interpreter interpreter) {
170 | SString arg = (SString) frame.pop();
171 | frame.pop();
172 |
173 | double d;
174 |
175 | try {
176 | d = Double.parseDouble(arg.getEmbeddedString());
177 | } catch (NumberFormatException e) {
178 | d = Double.NaN;
179 | }
180 |
181 | frame.push(universe.newDouble(d));
182 | }
183 | });
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/src/som/primitives/IntegerPrimitives.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.primitives;
26 |
27 | import java.math.BigInteger;
28 |
29 | import som.interpreter.Frame;
30 | import som.interpreter.Interpreter;
31 | import som.vm.Universe;
32 | import som.vmobjects.SAbstractObject;
33 | import som.vmobjects.SBigInteger;
34 | import som.vmobjects.SInteger;
35 | import som.vmobjects.SNumber;
36 | import som.vmobjects.SPrimitive;
37 | import som.vmobjects.SString;
38 |
39 |
40 | public class IntegerPrimitives extends Primitives {
41 |
42 | public IntegerPrimitives(final Universe universe) {
43 | super(universe);
44 | }
45 |
46 | @Override
47 | public void installPrimitives() {
48 | installInstancePrimitive(new SPrimitive("asString", universe) {
49 | @Override
50 | public void invoke(final Frame frame, final Interpreter interpreter) {
51 | SNumber self = (SNumber) frame.pop();
52 | frame.push(self.primAsString(universe));
53 | }
54 | });
55 |
56 | installInstancePrimitive(new SPrimitive("asDouble", universe) {
57 | @Override
58 | public void invoke(final Frame frame, final Interpreter interpreter) {
59 | SNumber self = (SNumber) frame.pop();
60 | frame.push(self.primAsDouble(universe));
61 | }
62 | });
63 |
64 | installInstancePrimitive(new SPrimitive("sqrt", universe) {
65 | @Override
66 | public void invoke(final Frame frame, final Interpreter interpreter) {
67 | SInteger self = (SInteger) frame.pop();
68 | frame.push(self.primSqrt(universe));
69 | }
70 | });
71 |
72 | installInstancePrimitive(new SPrimitive("atRandom", universe) {
73 | @Override
74 | public void invoke(final Frame frame, final Interpreter interpreter) {
75 | SInteger self = (SInteger) frame.pop();
76 | frame.push(universe.newInteger(
77 | (long) (self.getEmbeddedInteger() * Math.random())));
78 | }
79 | });
80 |
81 | installInstancePrimitive(new SPrimitive("+", universe) {
82 | @Override
83 | public void invoke(final Frame frame, final Interpreter interpreter) {
84 | SNumber right = (SNumber) frame.pop();
85 | SNumber left = (SNumber) frame.pop();
86 | frame.push(left.primAdd(right, universe));
87 | }
88 | });
89 |
90 | installInstancePrimitive(new SPrimitive("-", universe) {
91 | @Override
92 | public void invoke(final Frame frame, final Interpreter interpreter) {
93 | SNumber right = (SNumber) frame.pop();
94 | SNumber left = (SNumber) frame.pop();
95 | frame.push(left.primSubtract(right, universe));
96 | }
97 | });
98 |
99 | installInstancePrimitive(new SPrimitive("*", universe) {
100 | @Override
101 | public void invoke(final Frame frame, final Interpreter interpreter) {
102 | SNumber right = (SNumber) frame.pop();
103 | SNumber left = (SNumber) frame.pop();
104 | frame.push(left.primMultiply(right, universe));
105 | }
106 | });
107 |
108 | installInstancePrimitive(new SPrimitive("//", universe) {
109 | @Override
110 | public void invoke(final Frame frame, final Interpreter interpreter) {
111 | SNumber right = (SNumber) frame.pop();
112 | SNumber left = (SNumber) frame.pop();
113 | frame.push(left.primDoubleDivide(right, universe));
114 | }
115 | });
116 |
117 | installInstancePrimitive(new SPrimitive("/", universe) {
118 | @Override
119 | public void invoke(final Frame frame, final Interpreter interpreter) {
120 | SNumber right = (SNumber) frame.pop();
121 | SNumber left = (SNumber) frame.pop();
122 | frame.push(left.primIntegerDivide(right, universe));
123 | }
124 | });
125 |
126 | installInstancePrimitive(new SPrimitive("%", universe) {
127 | @Override
128 | public void invoke(final Frame frame, final Interpreter interpreter) {
129 | SNumber right = (SNumber) frame.pop();
130 | SNumber left = (SNumber) frame.pop();
131 | frame.push(left.primModulo(right, universe));
132 | }
133 | });
134 |
135 | installInstancePrimitive(new SPrimitive("rem:", universe) {
136 | @Override
137 | public void invoke(final Frame frame, final Interpreter interpreter) {
138 | SNumber right = (SNumber) frame.pop();
139 | SInteger left = (SInteger) frame.pop();
140 | frame.push(left.primRemainder(right, universe));
141 | }
142 | });
143 |
144 | installInstancePrimitive(new SPrimitive("&", universe) {
145 | @Override
146 | public void invoke(final Frame frame, final Interpreter interpreter) {
147 | SNumber right = (SNumber) frame.pop();
148 | SNumber left = (SNumber) frame.pop();
149 | frame.push(left.primBitAnd(right, universe));
150 | }
151 | });
152 |
153 | installInstancePrimitive(new SPrimitive("=", universe) {
154 | @Override
155 | public void invoke(final Frame frame, final Interpreter interpreter) {
156 | SAbstractObject right = frame.pop();
157 | SNumber left = (SNumber) frame.pop();
158 | frame.push(left.primEqual(right, universe));
159 | }
160 | });
161 |
162 | installInstancePrimitive(new SPrimitive("<", universe) {
163 | @Override
164 | public void invoke(final Frame frame, final Interpreter interpreter) {
165 | SNumber right = (SNumber) frame.pop();
166 | SNumber left = (SNumber) frame.pop();
167 | frame.push(left.primLessThan(right, universe));
168 | }
169 | });
170 |
171 | installInstancePrimitive(new SPrimitive("<<", universe) {
172 | @Override
173 | public void invoke(final Frame frame, final Interpreter interpreter) {
174 | SNumber right = (SNumber) frame.pop();
175 | SNumber left = (SNumber) frame.pop();
176 | frame.push(left.primLeftShift(right, universe));
177 | }
178 | });
179 |
180 | installInstancePrimitive(new SPrimitive("bitXor:", universe) {
181 | @Override
182 | public void invoke(final Frame frame, final Interpreter interpreter) {
183 | SNumber right = (SNumber) frame.pop();
184 | SNumber left = (SNumber) frame.pop();
185 | frame.push(left.primBitXor(right, universe));
186 | }
187 | });
188 |
189 | installInstancePrimitive(new SPrimitive("as32BitSignedValue", universe) {
190 | @Override
191 | public void invoke(final Frame frame, final Interpreter interpreter) {
192 | SNumber rcvr = (SNumber) frame.pop();
193 |
194 | int result;
195 | if (rcvr instanceof SInteger) {
196 | result = (int) ((SInteger) rcvr).getEmbeddedInteger();
197 | } else {
198 | result = ((SBigInteger) rcvr).getEmbeddedBiginteger().intValue();
199 | }
200 | frame.push(universe.newInteger(result));
201 | }
202 | });
203 |
204 | installInstancePrimitive(new SPrimitive("as32BitUnsignedValue", universe) {
205 | @Override
206 | public void invoke(final Frame frame, final Interpreter interpreter) {
207 | SInteger rcvr = (SInteger) frame.pop();
208 | frame.push(
209 | universe.newInteger(Integer.toUnsignedLong((int) rcvr.getEmbeddedInteger())));
210 | }
211 | });
212 |
213 | installInstancePrimitive(new SPrimitive(">>>", universe) {
214 | @Override
215 | public void invoke(final Frame frame, final Interpreter interpreter) {
216 | SInteger right = (SInteger) frame.pop();
217 | SInteger rcvr = (SInteger) frame.pop();
218 | frame.push(
219 | universe.newInteger(rcvr.getEmbeddedInteger() >>> right.getEmbeddedInteger()));
220 | }
221 | });
222 |
223 | installClassPrimitive(new SPrimitive("fromString:", universe) {
224 | @Override
225 | public void invoke(final Frame frame, final Interpreter interpreter) {
226 | SString param = (SString) frame.pop();
227 | frame.pop();
228 |
229 | try {
230 | long result = Long.parseLong(param.getEmbeddedString());
231 | frame.push(universe.newInteger(result));
232 | } catch (NumberFormatException e) {
233 | BigInteger result = new BigInteger(param.getEmbeddedString());
234 | frame.push(new SBigInteger(result));
235 | }
236 | }
237 | });
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/src/som/primitives/MethodPrimitives.java:
--------------------------------------------------------------------------------
1 | package som.primitives;
2 |
3 | import som.interpreter.Interpreter;
4 | import som.interpreter.Frame;
5 | import som.vm.Universe;
6 | import som.vmobjects.SMethod;
7 | import som.vmobjects.SPrimitive;
8 |
9 |
10 | public class MethodPrimitives extends Primitives {
11 | public MethodPrimitives(final Universe universe) {
12 | super(universe);
13 | }
14 |
15 | @Override
16 | public void installPrimitives() {
17 | installInstancePrimitive(new SPrimitive("holder", universe) {
18 |
19 | @Override
20 | public void invoke(Frame frame, Interpreter interpreter) {
21 | SMethod self = (SMethod) frame.pop();
22 | frame.push(self.getHolder());
23 | }
24 | });
25 |
26 | installInstancePrimitive(new SPrimitive("signature", universe) {
27 |
28 | @Override
29 | public void invoke(Frame frame, Interpreter interpreter) {
30 | SMethod self = (SMethod) frame.pop();
31 | frame.push(self.getSignature());
32 | }
33 | });
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/som/primitives/ObjectPrimitives.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2016 Michael Haupt, github@haupz.de
3 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
4 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
5 | * http://www.hpi.uni-potsdam.de/swa/
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package som.primitives;
27 |
28 | import som.interpreter.Frame;
29 | import som.interpreter.Interpreter;
30 | import som.vm.Universe;
31 | import som.vmobjects.SAbstractObject;
32 | import som.vmobjects.SArray;
33 | import som.vmobjects.SClass;
34 | import som.vmobjects.SInteger;
35 | import som.vmobjects.SInvokable;
36 | import som.vmobjects.SObject;
37 | import som.vmobjects.SPrimitive;
38 | import som.vmobjects.SSymbol;
39 |
40 |
41 | public class ObjectPrimitives extends Primitives {
42 |
43 | public ObjectPrimitives(final Universe universe) {
44 | super(universe);
45 | }
46 |
47 | @Override
48 | public void installPrimitives() {
49 |
50 | installInstancePrimitive(new SPrimitive("==", universe) {
51 | @Override
52 | public void invoke(final Frame frame, final Interpreter interpreter) {
53 | SAbstractObject op1 = frame.pop();
54 | SAbstractObject op2 = frame.pop();
55 | if (op1 == op2) {
56 | frame.push(universe.trueObject);
57 | } else {
58 | frame.push(universe.falseObject);
59 | }
60 | }
61 | });
62 |
63 | installInstancePrimitive(new SPrimitive("hashcode", universe) {
64 | @Override
65 | public void invoke(final Frame frame, final Interpreter interpreter) {
66 | SAbstractObject self = frame.pop();
67 | frame.push(universe.newInteger(self.hashCode()));
68 | }
69 | });
70 |
71 | installInstancePrimitive(new SPrimitive("objectSize", universe) {
72 | @Override
73 | public void invoke(final Frame frame, final Interpreter interpreter) {
74 | SAbstractObject self = frame.pop();
75 |
76 | // each object holds its class as an implicit member that contributes to its size
77 | int size = 1;
78 | if (self instanceof SArray) {
79 | size += ((SArray) self).getNumberOfIndexableFields();
80 | }
81 | if (self instanceof SObject) {
82 | size += ((SObject) self).getNumberOfFields();
83 | }
84 | frame.push(universe.newInteger(size));
85 | }
86 | });
87 |
88 | installInstancePrimitive(new SPrimitive("perform:", universe) {
89 | @Override
90 | public void invoke(final Frame frame, final Interpreter interpreter) {
91 | SAbstractObject arg = frame.pop();
92 | SAbstractObject self = frame.getStackElement(0);
93 | SSymbol selector = (SSymbol) arg;
94 |
95 | SInvokable invokable = self.getSOMClass(universe).lookupInvokable(selector);
96 | invokable.invoke(frame, interpreter);
97 | }
98 | });
99 |
100 | installInstancePrimitive(new SPrimitive("perform:inSuperclass:", universe) {
101 | @Override
102 | public void invoke(final Frame frame, final Interpreter interpreter) {
103 | SAbstractObject arg2 = frame.pop();
104 | SAbstractObject arg = frame.pop();
105 | // Object self = frame.getStackElement(0);
106 |
107 | SSymbol selector = (SSymbol) arg;
108 | SClass clazz = (SClass) arg2;
109 |
110 | SInvokable invokable = clazz.lookupInvokable(selector);
111 | invokable.invoke(frame, interpreter);
112 | }
113 | });
114 |
115 | installInstancePrimitive(new SPrimitive("perform:withArguments:", universe) {
116 | @Override
117 | public void invoke(final Frame frame, final Interpreter interpreter) {
118 | SAbstractObject arg2 = frame.pop();
119 | SAbstractObject arg = frame.pop();
120 | SAbstractObject self = frame.getStackElement(0);
121 |
122 | SSymbol selector = (SSymbol) arg;
123 | SArray args = (SArray) arg2;
124 |
125 | for (int i = 0; i < args.getNumberOfIndexableFields(); i++) {
126 | frame.push(args.getIndexableField(i));
127 | }
128 |
129 | SInvokable invokable = self.getSOMClass(universe).lookupInvokable(selector);
130 | invokable.invoke(frame, interpreter);
131 | }
132 | });
133 |
134 | installInstancePrimitive(new SPrimitive("instVarAt:", universe) {
135 | @Override
136 | public void invoke(final Frame frame, final Interpreter interpreter) {
137 | SAbstractObject arg = frame.pop();
138 | SObject self = (SObject) frame.pop();
139 | SInteger idx = (SInteger) arg;
140 |
141 | frame.push(self.getField(idx.getEmbeddedInteger() - 1));
142 | }
143 | });
144 |
145 | installInstancePrimitive(new SPrimitive("instVarAt:put:", universe) {
146 | @Override
147 | public void invoke(final Frame frame, final Interpreter interpreter) {
148 | SAbstractObject val = frame.pop();
149 | SAbstractObject arg = frame.pop();
150 | SObject self = (SObject) frame.getStackElement(0);
151 |
152 | SInteger idx = (SInteger) arg;
153 |
154 | self.setField(idx.getEmbeddedInteger() - 1, val);
155 | }
156 | });
157 |
158 | installInstancePrimitive(new SPrimitive("class", universe) {
159 | @Override
160 | public void invoke(final Frame frame, final Interpreter interpreter) {
161 | SAbstractObject self = frame.pop();
162 | frame.push(self.getSOMClass(universe));
163 | }
164 | });
165 |
166 | installInstancePrimitive(new SPrimitive("halt", universe) {
167 | @Override
168 | public void invoke(final Frame frame, final Interpreter interpreter) {
169 | Universe.errorPrintln("BREAKPOINT");
170 | }
171 | });
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/src/som/primitives/PrimitivePrimitives.java:
--------------------------------------------------------------------------------
1 | package som.primitives;
2 |
3 | import som.interpreter.Interpreter;
4 | import som.interpreter.Frame;
5 | import som.vm.Universe;
6 | import som.vmobjects.SPrimitive;
7 |
8 |
9 | public class PrimitivePrimitives extends Primitives {
10 | public PrimitivePrimitives(final Universe universe) {
11 | super(universe);
12 | }
13 |
14 | @Override
15 | public void installPrimitives() {
16 | installInstancePrimitive(new SPrimitive("holder", universe) {
17 |
18 | @Override
19 | public void invoke(Frame frame, Interpreter interpreter) {
20 | SPrimitive self = (SPrimitive) frame.pop();
21 | frame.push(self.getHolder());
22 | }
23 | });
24 |
25 | installInstancePrimitive(new SPrimitive("signature", universe) {
26 |
27 | @Override
28 | public void invoke(Frame frame, Interpreter interpreter) {
29 | SPrimitive self = (SPrimitive) frame.pop();
30 | frame.push(self.getSignature());
31 | }
32 | });
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/som/primitives/Primitives.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2013 Stefan Marr, stefan.marr@vub.ac.be
3 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
4 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
5 | * http://www.hpi.uni-potsdam.de/swa/
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package som.primitives;
27 |
28 | import som.vm.Universe;
29 | import som.vmobjects.SClass;
30 | import som.vmobjects.SPrimitive;
31 |
32 |
33 | public abstract class Primitives {
34 |
35 | protected final Universe universe;
36 |
37 | public Primitives(final Universe universe) {
38 | this.universe = universe;
39 | }
40 |
41 | public final void installPrimitivesIn(final SClass value) {
42 | // Save a reference to the holder class
43 | holder = value;
44 |
45 | // Install the primitives from this primitives class
46 | installPrimitives();
47 | }
48 |
49 | public abstract void installPrimitives();
50 |
51 | protected void installInstancePrimitive(final SPrimitive primitive) {
52 | installInstancePrimitive(primitive, false);
53 | }
54 |
55 | protected void installInstancePrimitive(final SPrimitive primitive,
56 | final boolean suppressWarning) {
57 | // Install the given primitive as an instance primitive in the holder
58 | // class
59 | holder.addInstancePrimitive(primitive, suppressWarning);
60 | }
61 |
62 | protected void installClassPrimitive(final SPrimitive primitive) {
63 | // Install the given primitive as an instance primitive in the class of
64 | // the holder class
65 | holder.getSOMClass().addInstancePrimitive(primitive);
66 | }
67 |
68 | private SClass holder;
69 | }
70 |
--------------------------------------------------------------------------------
/src/som/primitives/StringPrimitives.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2013 Stefan Marr, stefan.marr@vub.ac.be
3 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
4 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
5 | * http://www.hpi.uni-potsdam.de/swa/
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package som.primitives;
27 |
28 | import som.interpreter.Frame;
29 | import som.interpreter.Interpreter;
30 | import som.vm.Universe;
31 | import som.vmobjects.SAbstractObject;
32 | import som.vmobjects.SInteger;
33 | import som.vmobjects.SPrimitive;
34 | import som.vmobjects.SString;
35 |
36 |
37 | public class StringPrimitives extends Primitives {
38 |
39 | public StringPrimitives(final Universe universe) {
40 | super(universe);
41 | }
42 |
43 | @Override
44 | public void installPrimitives() {
45 | installInstancePrimitive(new SPrimitive("concatenate:", universe) {
46 |
47 | @Override
48 | public void invoke(final Frame frame, final Interpreter interpreter) {
49 | SString argument = (SString) frame.pop();
50 | SString self = (SString) frame.pop();
51 | frame.push(universe.newString(self.getEmbeddedString()
52 | + argument.getEmbeddedString()));
53 | }
54 | });
55 |
56 | installInstancePrimitive(new SPrimitive("asSymbol", universe) {
57 |
58 | @Override
59 | public void invoke(final Frame frame, final Interpreter interpreter) {
60 | SString self = (SString) frame.pop();
61 | frame.push(universe.symbolFor(self.getEmbeddedString()));
62 | }
63 | });
64 |
65 | installInstancePrimitive(new SPrimitive("length", universe) {
66 |
67 | @Override
68 | public void invoke(final Frame frame, final Interpreter interpreter) {
69 | SString self = (SString) frame.pop();
70 | frame.push(universe.newInteger(self.getEmbeddedString().length()));
71 | }
72 | });
73 |
74 | installInstancePrimitive(new SPrimitive("=", universe) {
75 |
76 | @Override
77 | public void invoke(final Frame frame, final Interpreter interpreter) {
78 | SAbstractObject op2 = frame.pop();
79 | SString op1 = (SString) frame.pop(); // self
80 | if (op2 instanceof SString) {
81 | SString s = (SString) op2;
82 | if (s.getEmbeddedString().equals(op1.getEmbeddedString())) {
83 | frame.push(universe.trueObject);
84 | return;
85 | }
86 | }
87 |
88 | frame.push(universe.falseObject);
89 | }
90 | });
91 |
92 | installInstancePrimitive(new SPrimitive("primSubstringFrom:to:", universe) {
93 |
94 | @Override
95 | public void invoke(final Frame frame, final Interpreter interpreter) {
96 | SInteger end = (SInteger) frame.pop();
97 | SInteger start = (SInteger) frame.pop();
98 |
99 | SString self = (SString) frame.pop();
100 |
101 | try {
102 | frame.push(universe.newString(self.getEmbeddedString().substring(
103 | (int) start.getEmbeddedInteger() - 1,
104 | (int) end.getEmbeddedInteger())));
105 | } catch (IndexOutOfBoundsException e) {
106 | frame.push(universe.newString(new java.lang.String(
107 | "Error - index out of bounds")));
108 | }
109 | }
110 | });
111 |
112 | installInstancePrimitive(new SPrimitive("hashcode", universe) {
113 |
114 | @Override
115 | public void invoke(final Frame frame, final Interpreter interpreter) {
116 | SString self = (SString) frame.pop();
117 | frame.push(universe.newInteger(self.getEmbeddedString().hashCode()));
118 | }
119 | });
120 |
121 | installInstancePrimitive(new SPrimitive("isWhiteSpace", universe) {
122 |
123 | @Override
124 | public void invoke(final Frame frame, final Interpreter interpreter) {
125 | SString self = (SString) frame.pop();
126 | String embedded = self.getEmbeddedString();
127 |
128 | for (int i = 0; i < embedded.length(); i++) {
129 | if (!Character.isWhitespace(embedded.charAt(i))) {
130 | frame.push(universe.falseObject);
131 | return;
132 | }
133 | }
134 |
135 | if (embedded.length() > 0) {
136 | frame.push(universe.trueObject);
137 | } else {
138 | frame.push(universe.falseObject);
139 | }
140 | }
141 | });
142 |
143 | installInstancePrimitive(new SPrimitive("isLetters", universe) {
144 |
145 | @Override
146 | public void invoke(final Frame frame, final Interpreter interpreter) {
147 | SString self = (SString) frame.pop();
148 | String embedded = self.getEmbeddedString();
149 |
150 | for (int i = 0; i < embedded.length(); i++) {
151 | if (!Character.isLetter(embedded.charAt(i))) {
152 | frame.push(universe.falseObject);
153 | return;
154 | }
155 | }
156 |
157 | if (embedded.length() > 0) {
158 | frame.push(universe.trueObject);
159 | } else {
160 | frame.push(universe.falseObject);
161 | }
162 | }
163 | });
164 |
165 | installInstancePrimitive(new SPrimitive("isDigits", universe) {
166 |
167 | @Override
168 | public void invoke(final Frame frame, final Interpreter interpreter) {
169 | SString self = (SString) frame.pop();
170 | String embedded = self.getEmbeddedString();
171 |
172 | for (int i = 0; i < embedded.length(); i++) {
173 | if (!Character.isDigit(embedded.charAt(i))) {
174 | frame.push(universe.falseObject);
175 | return;
176 | }
177 | }
178 |
179 | if (embedded.length() > 0) {
180 | frame.push(universe.trueObject);
181 | } else {
182 | frame.push(universe.falseObject);
183 | }
184 | }
185 | });
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/src/som/primitives/SymbolPrimitives.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.primitives;
26 |
27 | import som.interpreter.Frame;
28 | import som.interpreter.Interpreter;
29 | import som.vm.Universe;
30 | import som.vmobjects.SAbstractObject;
31 | import som.vmobjects.SPrimitive;
32 | import som.vmobjects.SString;
33 | import som.vmobjects.SSymbol;
34 |
35 |
36 | public class SymbolPrimitives extends Primitives {
37 |
38 | public SymbolPrimitives(final Universe universe) {
39 | super(universe);
40 | }
41 |
42 | @Override
43 | public void installPrimitives() {
44 | installInstancePrimitive(new SPrimitive("asString", universe) {
45 |
46 | @Override
47 | public void invoke(final Frame frame, final Interpreter interpreter) {
48 | SSymbol self = (SSymbol) frame.pop();
49 | frame.push(universe.newString(self.getEmbeddedString()));
50 | }
51 | });
52 |
53 | installInstancePrimitive(new SPrimitive("=", universe) {
54 |
55 | @Override
56 | public void invoke(final Frame frame, final Interpreter interpreter) {
57 | SAbstractObject op1 = frame.pop();
58 | SSymbol op2 = (SSymbol) frame.pop(); // self
59 | if (op1 == op2) {
60 | frame.push(universe.trueObject);
61 | return;
62 | }
63 |
64 | if (op1 instanceof SString) {
65 | SString s = (SString) op1;
66 | if (s.getEmbeddedString().equals(op2.getEmbeddedString())) {
67 | frame.push(universe.trueObject);
68 | return;
69 | }
70 | }
71 | frame.push(universe.falseObject);
72 | }
73 | }, true);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/som/primitives/SystemPrimitives.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.primitives;
26 |
27 | import java.io.IOException;
28 | import java.lang.management.GarbageCollectorMXBean;
29 | import java.lang.management.ManagementFactory;
30 | import java.nio.file.Files;
31 | import java.nio.file.Path;
32 | import java.nio.file.Paths;
33 | import java.util.List;
34 |
35 | import com.sun.management.ThreadMXBean;
36 | import som.compiler.ProgramDefinitionError;
37 | import som.interpreter.Frame;
38 | import som.interpreter.Interpreter;
39 | import som.vm.Universe;
40 | import som.vmobjects.SAbstractObject;
41 | import som.vmobjects.SArray;
42 | import som.vmobjects.SClass;
43 | import som.vmobjects.SInteger;
44 | import som.vmobjects.SPrimitive;
45 | import som.vmobjects.SString;
46 | import som.vmobjects.SSymbol;
47 |
48 |
49 | public class SystemPrimitives extends Primitives {
50 |
51 | public SystemPrimitives(final Universe universe) {
52 | super(universe);
53 | }
54 |
55 | @Override
56 | public void installPrimitives() {
57 | installInstancePrimitive(new SPrimitive("load:", universe) {
58 |
59 | @Override
60 | public void invoke(final Frame frame, final Interpreter interpreter) {
61 | SSymbol argument = (SSymbol) frame.pop();
62 | frame.pop(); // not required
63 | SClass result = null;
64 | try {
65 | result = universe.loadClass(argument);
66 | } catch (ProgramDefinitionError e) {
67 | universe.errorExit(e.toString());
68 | }
69 | frame.push(result != null ? result : universe.nilObject);
70 | }
71 | });
72 |
73 | installInstancePrimitive(new SPrimitive("exit:", universe) {
74 |
75 | @Override
76 | public void invoke(final Frame frame, final Interpreter interpreter) {
77 | SInteger error = (SInteger) frame.pop();
78 | universe.exit(error.getEmbeddedInteger());
79 | }
80 | });
81 |
82 | installInstancePrimitive(new SPrimitive("global:", universe) {
83 |
84 | @Override
85 | public void invoke(final Frame frame, final Interpreter interpreter) {
86 | SSymbol argument = (SSymbol) frame.pop();
87 | frame.pop(); // not required
88 | SAbstractObject result = universe.getGlobal(argument);
89 | frame.push(result != null ? result : universe.nilObject);
90 | }
91 | });
92 |
93 | installInstancePrimitive(new SPrimitive("global:put:", universe) {
94 |
95 | @Override
96 | public void invoke(final Frame frame, final Interpreter interpreter) {
97 | SAbstractObject value = frame.pop();
98 | SSymbol argument = (SSymbol) frame.pop();
99 | universe.setGlobal(argument, value);
100 | }
101 | });
102 |
103 | installInstancePrimitive(new SPrimitive("printString:", universe) {
104 |
105 | @Override
106 | public void invoke(final Frame frame, final Interpreter interpreter) {
107 | SString argument = (SString) frame.pop();
108 | Universe.print(argument.getEmbeddedString());
109 | }
110 | });
111 |
112 | installInstancePrimitive(new SPrimitive("printNewline", universe) {
113 |
114 | @Override
115 | public void invoke(final Frame frame, final Interpreter interpreter) {
116 | Universe.println("");
117 | }
118 | });
119 |
120 | installInstancePrimitive(new SPrimitive("errorPrint:", universe) {
121 |
122 | @Override
123 | public void invoke(final Frame frame, final Interpreter interpreter) {
124 | SString argument = (SString) frame.pop();
125 | Universe.errorPrint(argument.getEmbeddedString());
126 | }
127 | });
128 |
129 | installInstancePrimitive(new SPrimitive("errorPrintln:", universe) {
130 |
131 | @Override
132 | public void invoke(final Frame frame, final Interpreter interpreter) {
133 | SString argument = (SString) frame.pop();
134 | Universe.errorPrintln(argument.getEmbeddedString());
135 | }
136 | });
137 |
138 | startMicroTime = System.nanoTime() / 1000L;
139 | startTime = startMicroTime / 1000L;
140 | installInstancePrimitive(new SPrimitive("time", universe) {
141 |
142 | @Override
143 | public void invoke(final Frame frame, final Interpreter interpreter) {
144 | frame.pop(); // ignore
145 | int time = (int) (System.currentTimeMillis() - startTime);
146 | frame.push(universe.newInteger(time));
147 | }
148 | });
149 |
150 | installInstancePrimitive(new SPrimitive("ticks", universe) {
151 |
152 | @Override
153 | public void invoke(final Frame frame, final Interpreter interpreter) {
154 | frame.pop(); // ignore
155 | int time = (int) (System.nanoTime() / 1000L - startMicroTime);
156 | frame.push(universe.newInteger(time));
157 | }
158 | });
159 |
160 | installInstancePrimitive(new SPrimitive("fullGC", universe) {
161 |
162 | @Override
163 | public void invoke(final Frame frame, final Interpreter interpreter) {
164 | frame.pop();
165 | System.gc();
166 | frame.push(universe.trueObject);
167 | }
168 | });
169 |
170 | installInstancePrimitive(new SPrimitive("gcStats", universe) {
171 |
172 | @Override
173 | public void invoke(Frame frame, Interpreter interpreter) {
174 | frame.pop();
175 |
176 | final List gcBeans =
177 | ManagementFactory.getGarbageCollectorMXBeans();
178 | final ThreadMXBean threadBean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
179 | threadBean.setThreadAllocatedMemoryEnabled(true);
180 |
181 | final long allocatedBytes = threadBean.getCurrentThreadAllocatedBytes();
182 | long counts = 0;
183 | long time = 0;
184 |
185 | for (GarbageCollectorMXBean b : gcBeans) {
186 | long c = b.getCollectionCount();
187 | if (c != -1) {
188 | counts += c;
189 | }
190 |
191 | long t = b.getCollectionTime();
192 | if (t != -1) {
193 | time += t;
194 | }
195 | }
196 |
197 | final SArray arr = new SArray(universe.nilObject, 3L);
198 | arr.setIndexableField(0L, SInteger.getInteger(counts));
199 | arr.setIndexableField(1L, SInteger.getInteger(time));
200 | arr.setIndexableField(2L, SInteger.getInteger(allocatedBytes));
201 |
202 | frame.push(arr);
203 | }
204 | });
205 |
206 | installInstancePrimitive(new SPrimitive("loadFile:", universe) {
207 |
208 | @Override
209 | public void invoke(final Frame frame, final Interpreter interpreter) {
210 | SString fileName = (SString) frame.pop();
211 | frame.pop();
212 |
213 | Path p = Paths.get(fileName.getEmbeddedString());
214 | try {
215 | String content = new String(Files.readAllBytes(p));
216 | frame.push(universe.newString(content));
217 | } catch (IOException e) {
218 | frame.push(universe.nilObject);
219 | }
220 | }
221 | });
222 |
223 | installInstancePrimitive(new SPrimitive("printStackTrace", universe) {
224 |
225 | @Override
226 | public void invoke(final Frame frame, final Interpreter interpreter) {
227 | frame.pop();
228 | frame.printStackTrace();
229 | frame.push(universe.trueObject);
230 | }
231 | });
232 | }
233 |
234 | private long startTime;
235 | private long startMicroTime;
236 | }
237 |
--------------------------------------------------------------------------------
/src/som/vm/Shell.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Michael Haupt, github@haupz.de
3 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
4 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
5 | * http://www.hpi.uni-potsdam.de/swa/
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package som.vm;
27 |
28 | import java.io.BufferedReader;
29 | import java.io.InputStreamReader;
30 |
31 | import som.interpreter.Frame;
32 | import som.interpreter.Interpreter;
33 | import som.vmobjects.SAbstractObject;
34 | import som.vmobjects.SClass;
35 | import som.vmobjects.SInvokable;
36 | import som.vmobjects.SMethod;
37 |
38 |
39 | public class Shell {
40 |
41 | private final Universe universe;
42 | private final Interpreter interpreter;
43 |
44 | public Shell(final Universe universe, final Interpreter interpreter) {
45 | this.universe = universe;
46 | this.interpreter = interpreter;
47 | }
48 |
49 | private SMethod bootstrapMethod;
50 |
51 | public void setBootstrapMethod(SMethod method) {
52 | bootstrapMethod = method;
53 | }
54 |
55 | public SAbstractObject start() {
56 |
57 | BufferedReader in;
58 | String stmt;
59 | int counter;
60 | int bytecodeIndex;
61 | SClass myClass;
62 | SAbstractObject myObject;
63 | SAbstractObject it;
64 | Frame currentFrame;
65 |
66 | counter = 0;
67 | in = new BufferedReader(new InputStreamReader(System.in));
68 | it = universe.nilObject;
69 |
70 | Universe.println("SOM Shell. Type \"quit\" to exit.\n");
71 |
72 | // Create a fake bootstrap frame
73 | currentFrame = interpreter.pushNewFrame(bootstrapMethod);
74 |
75 | // Remember the first bytecode index, e.g. index of the HALT instruction
76 | bytecodeIndex = currentFrame.getBytecodeIndex();
77 |
78 | while (true) {
79 | try {
80 | Universe.print("---> ");
81 |
82 | // Read a statement from the keyboard
83 | stmt = in.readLine();
84 | if (stmt.equals("quit")) {
85 | return it;
86 | }
87 |
88 | // Generate a temporary class with a run method
89 | stmt = "Shell_Class_" + counter++ + " = ( run: it = ( | tmp | tmp := ("
90 | + stmt + " ). 'it = ' print. ^tmp println ) )";
91 |
92 | // Compile and load the newly generated class
93 | myClass = universe.loadShellClass(stmt);
94 |
95 | // If success
96 | if (myClass != null) {
97 | currentFrame = interpreter.getFrame();
98 |
99 | // Go back, so we will evaluate the bootstrap frames halt
100 | // instruction again
101 | currentFrame.setBytecodeIndex(bytecodeIndex);
102 |
103 | // Create and push a new instance of our class on the stack
104 | myObject = universe.newInstance(myClass);
105 | currentFrame.push(myObject);
106 |
107 | // Push the old value of "it" on the stack
108 | currentFrame.push(it);
109 |
110 | // Lookup the run: method
111 | SInvokable initialize = myClass.lookupInvokable(
112 | universe.symbolFor("run:"));
113 |
114 | // Invoke the run method
115 | initialize.invoke(currentFrame, interpreter);
116 |
117 | // Start the interpreter
118 | interpreter.start();
119 |
120 | // Save the result of the run method
121 | it = currentFrame.pop();
122 | }
123 | } catch (Exception e) {
124 | Universe.errorPrintln("Caught exception: " + e.getMessage());
125 | Universe.errorPrintln("" + interpreter.getFrame().getPreviousFrame());
126 | }
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SAbstractObject.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.vmobjects;
26 |
27 | import som.interpreter.Frame;
28 | import som.interpreter.Interpreter;
29 | import som.vm.Universe;
30 |
31 |
32 | public abstract class SAbstractObject {
33 |
34 | public abstract SClass getSOMClass(Universe universe);
35 |
36 | public void send(final String selectorString, final SAbstractObject[] arguments,
37 | final Universe universe, final Interpreter interpreter) {
38 | // Turn the selector string into a selector
39 | SSymbol selector = universe.symbolFor(selectorString);
40 |
41 | // Push the receiver onto the stack
42 | interpreter.getFrame().push(this);
43 |
44 | // Push the arguments onto the stack
45 | for (SAbstractObject arg : arguments) {
46 | interpreter.getFrame().push(arg);
47 | }
48 |
49 | // Lookup the invokable
50 | SInvokable invokable = getSOMClass(universe).lookupInvokable(selector);
51 |
52 | // Invoke the invokable
53 | invokable.invoke(interpreter.getFrame(), interpreter);
54 | }
55 |
56 | public void sendDoesNotUnderstand(final SSymbol selector,
57 | final Universe universe, final Interpreter interpreter) {
58 | // Compute the number of arguments
59 | int numberOfArguments = selector.getNumberOfSignatureArguments();
60 |
61 | Frame frame = interpreter.getFrame();
62 |
63 | // Allocate an array with enough room to hold all arguments
64 | // except for the receiver, which is passed implicitly, as receiver of #dnu.
65 | SArray argumentsArray = universe.newArray(numberOfArguments - 1);
66 |
67 | // Remove all arguments and put them in the freshly allocated array
68 | for (int i = numberOfArguments - 2; i >= 0; i--) {
69 | argumentsArray.setIndexableField(i, frame.pop());
70 | }
71 |
72 | frame.pop(); // pop receiver
73 |
74 | SAbstractObject[] args = {selector, argumentsArray};
75 | send("doesNotUnderstand:arguments:", args, universe, interpreter);
76 | }
77 |
78 | public void sendUnknownGlobal(final SSymbol globalName,
79 | final Universe universe, final Interpreter interpreter) {
80 | SAbstractObject[] arguments = {globalName};
81 | send("unknownGlobal:", arguments, universe, interpreter);
82 | }
83 |
84 | public void sendEscapedBlock(final SBlock block, final Universe universe,
85 | final Interpreter interpreter) {
86 | SAbstractObject[] arguments = {block};
87 | send("escapedBlock:", arguments, universe, interpreter);
88 | }
89 |
90 | @Override
91 | public String toString() {
92 | return "a " + getSOMClass(Universe.current()).getName().getEmbeddedString();
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SArray.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.vmobjects;
26 |
27 | import som.vm.Universe;
28 |
29 |
30 | public class SArray extends SAbstractObject {
31 |
32 | public SArray(final SObject nilObject, long numElements) {
33 | indexableFields = new SAbstractObject[(int) numElements];
34 |
35 | // Clear each and every field by putting nil into them
36 | for (int i = 0; i < getNumberOfIndexableFields(); i++) {
37 | setIndexableField(i, nilObject);
38 | }
39 | }
40 |
41 | public SAbstractObject getIndexableField(long index) {
42 | return indexableFields[(int) index];
43 | }
44 |
45 | public void setIndexableField(long index, SAbstractObject value) {
46 | indexableFields[(int) index] = value;
47 | }
48 |
49 | public int getNumberOfIndexableFields() {
50 | return indexableFields.length;
51 | }
52 |
53 | public SArray copyAndExtendWith(SAbstractObject value, final Universe universe) {
54 | // Allocate a new array which has one indexable field more than this
55 | // array
56 | SArray result = universe.newArray(getNumberOfIndexableFields() + 1);
57 |
58 | // Copy the indexable fields from this array to the new array
59 | copyIndexableFieldsTo(result);
60 |
61 | // Insert the given object as the last indexable field in the new array
62 | result.setIndexableField(getNumberOfIndexableFields(), value);
63 |
64 | return result;
65 | }
66 |
67 | protected void copyIndexableFieldsTo(SArray destination) {
68 | // Copy all indexable fields from this array to the destination array
69 | for (int i = 0; i < getNumberOfIndexableFields(); i++) {
70 | destination.setIndexableField(i, getIndexableField(i));
71 | }
72 | }
73 |
74 | @Override
75 | public SClass getSOMClass(final Universe universe) {
76 | return universe.arrayClass;
77 | }
78 |
79 | // Private array of indexable fields
80 | private final SAbstractObject[] indexableFields;
81 | }
82 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SBigInteger.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.vmobjects;
26 |
27 | import java.math.BigInteger;
28 |
29 | import som.vm.Universe;
30 |
31 |
32 | public final class SBigInteger extends SNumber {
33 |
34 | // Private variable holding the embedded big integer
35 | private final BigInteger embeddedBiginteger;
36 |
37 | public SBigInteger(final BigInteger value) {
38 | embeddedBiginteger = value;
39 | }
40 |
41 | public BigInteger getEmbeddedBiginteger() {
42 | // Get the embedded big integer
43 | return embeddedBiginteger;
44 | }
45 |
46 | @Override
47 | public String toString() {
48 | return super.toString() + "(" + embeddedBiginteger + ")";
49 | }
50 |
51 | @Override
52 | public SClass getSOMClass(final Universe universe) {
53 | return universe.integerClass;
54 | }
55 |
56 | @Override
57 | public SString primAsString(final Universe universe) {
58 | return universe.newString(embeddedBiginteger.toString());
59 | }
60 |
61 | @Override
62 | public SNumber primAsDouble(final Universe universe) {
63 | return universe.newDouble(embeddedBiginteger.doubleValue());
64 | }
65 |
66 | private SNumber asSNumber(final BigInteger result, final Universe universe) {
67 | if (result.bitLength() >= Long.SIZE) {
68 | return universe.newBigInteger(result);
69 | } else {
70 | return universe.newInteger(result.longValue());
71 | }
72 | }
73 |
74 | private BigInteger asBigInteger(final SNumber right) {
75 | BigInteger r;
76 | if (right instanceof SInteger) {
77 | r = BigInteger.valueOf(((SInteger) right).getEmbeddedInteger());
78 | } else {
79 | r = ((SBigInteger) right).embeddedBiginteger;
80 | }
81 | return r;
82 | }
83 |
84 | @Override
85 | public SNumber primAdd(final SNumber right, final Universe universe) {
86 | if (right instanceof SDouble) {
87 | return universe.newDouble(
88 | embeddedBiginteger.doubleValue() + ((SDouble) right).getEmbeddedDouble());
89 | }
90 | BigInteger r = asBigInteger(right);
91 | BigInteger result = embeddedBiginteger.add(r);
92 | return asSNumber(result, universe);
93 | }
94 |
95 | @Override
96 | public SNumber primSubtract(final SNumber right, final Universe universe) {
97 | if (right instanceof SDouble) {
98 | return universe.newDouble(
99 | embeddedBiginteger.doubleValue() - ((SDouble) right).getEmbeddedDouble());
100 | }
101 | BigInteger r = asBigInteger(right);
102 | BigInteger result = embeddedBiginteger.subtract(r);
103 | return asSNumber(result, universe);
104 | }
105 |
106 | @Override
107 | public SNumber primMultiply(final SNumber right, final Universe universe) {
108 | if (right instanceof SDouble) {
109 | return universe.newDouble(
110 | embeddedBiginteger.doubleValue() * ((SDouble) right).getEmbeddedDouble());
111 | }
112 | BigInteger r = asBigInteger(right);
113 | BigInteger result = embeddedBiginteger.multiply(r);
114 | return asSNumber(result, universe);
115 | }
116 |
117 | @Override
118 | public SNumber primDoubleDivide(final SNumber right, final Universe universe) {
119 | double r;
120 | if (right instanceof SInteger) {
121 | r = ((SInteger) right).getEmbeddedInteger();
122 | } else {
123 | r = ((SBigInteger) right).embeddedBiginteger.doubleValue();
124 | }
125 | double result = embeddedBiginteger.doubleValue() / r;
126 | return universe.newDouble(result);
127 | }
128 |
129 | @Override
130 | public SNumber primIntegerDivide(final SNumber right, final Universe universe) {
131 | BigInteger r = asBigInteger(right);
132 | BigInteger result = embeddedBiginteger.divide(r);
133 | return asSNumber(result, universe);
134 | }
135 |
136 | @Override
137 | public SNumber primModulo(final SNumber right, final Universe universe) {
138 | BigInteger r = asBigInteger(right);
139 | BigInteger result = embeddedBiginteger.mod(r);
140 | return asSNumber(result, universe);
141 | }
142 |
143 | @Override
144 | public SNumber primSqrt(final Universe universe) {
145 | double result = Math.sqrt(embeddedBiginteger.doubleValue());
146 |
147 | if (result == Math.rint(result)) {
148 | return intOrBigInt(result, universe);
149 | } else {
150 | return universe.newDouble(result);
151 | }
152 | }
153 |
154 | @Override
155 | public SNumber primBitAnd(final SNumber right, final Universe universe) {
156 | BigInteger r = asBigInteger(right);
157 | BigInteger result = embeddedBiginteger.and(r);
158 | return asSNumber(result, universe);
159 | }
160 |
161 | @Override
162 | public SObject primEqual(final SAbstractObject right, final Universe universe) {
163 | if (!(right instanceof SNumber)) {
164 | return universe.falseObject;
165 | }
166 |
167 | BigInteger r = asBigInteger((SNumber) right);
168 |
169 | if (embeddedBiginteger.compareTo(r) == 0) {
170 | return universe.trueObject;
171 | } else {
172 | return universe.falseObject;
173 | }
174 | }
175 |
176 | @Override
177 | public SObject primLessThan(final SNumber right, final Universe universe) {
178 | BigInteger r = asBigInteger(right);
179 | if (embeddedBiginteger.compareTo(r) < 0) {
180 | return universe.trueObject;
181 | } else {
182 | return universe.falseObject;
183 | }
184 | }
185 |
186 | @Override
187 | public SNumber primLeftShift(final SNumber right, final Universe universe) {
188 | BigInteger r = asBigInteger(right);
189 | return universe.newBigInteger(embeddedBiginteger.shiftLeft(r.intValue()));
190 | }
191 |
192 | @Override
193 | public SNumber primBitXor(final SNumber right, final Universe universe) {
194 | BigInteger r = asBigInteger(right);
195 | BigInteger result = embeddedBiginteger.xor(r);
196 | return asSNumber(result, universe);
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SBlock.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.vmobjects;
26 |
27 | import som.interpreter.Frame;
28 | import som.interpreter.Interpreter;
29 | import som.vm.Universe;
30 |
31 |
32 | public class SBlock extends SAbstractObject {
33 |
34 | public SBlock(final SMethod method, final Frame context, final SClass blockClass) {
35 | this.method = method;
36 | this.context = context;
37 | this.blockClass = blockClass;
38 | }
39 |
40 | public SMethod getMethod() {
41 | return method;
42 | }
43 |
44 | public Frame getContext() {
45 | return context;
46 | }
47 |
48 | @Override
49 | public SClass getSOMClass(final Universe universe) {
50 | return blockClass;
51 | }
52 |
53 | public static SPrimitive getEvaluationPrimitive(final int numberOfArguments,
54 | final Universe universe) {
55 | return new Evaluation(numberOfArguments, universe);
56 | }
57 |
58 | public static class Evaluation extends SPrimitive {
59 |
60 | public Evaluation(final int numberOfArguments, final Universe universe) {
61 | super(computeSignatureString(numberOfArguments), universe);
62 | this.numberOfArguments = numberOfArguments;
63 | }
64 |
65 | @Override
66 | public void invoke(final Frame frame, final Interpreter interpreter) {
67 | // Get the block (the receiver) from the stack
68 | SBlock self = (SBlock) frame.getStackElement(numberOfArguments - 1);
69 |
70 | // Get the context of the block...
71 | Frame context = self.getContext();
72 |
73 | // Push a new frame and set its context to be the one specified in
74 | // the block
75 | Frame newFrame = interpreter.pushNewFrame(self.getMethod(), context);
76 | newFrame.copyArgumentsFrom(frame);
77 | }
78 |
79 | private static String computeSignatureString(final int numberOfArguments) {
80 | // Compute the signature string
81 | String signatureString = "value";
82 | if (numberOfArguments > 1) {
83 | signatureString += ":";
84 | }
85 |
86 | // Add extra value: selector elements if necessary
87 | for (int i = 2; i < numberOfArguments; i++) {
88 | signatureString += "with:";
89 | }
90 |
91 | // Return the signature string
92 | return signatureString;
93 | }
94 |
95 | private final int numberOfArguments;
96 | }
97 |
98 | private final SMethod method;
99 | private final Frame context;
100 | private final SClass blockClass;
101 | }
102 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SClass.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.vmobjects;
26 |
27 | import java.lang.reflect.Constructor;
28 | import java.util.HashMap;
29 |
30 | import som.primitives.Primitives;
31 | import som.vm.Universe;
32 |
33 |
34 | public class SClass extends SObject {
35 |
36 | private final Universe universe;
37 |
38 | public SClass(final Universe universe) {
39 | // Initialize this class by calling the super constructor
40 | super(universe.nilObject);
41 | invokablesTable = new HashMap();
42 | this.universe = universe;
43 | }
44 |
45 | public SClass(final int numberOfFields, final Universe universe) {
46 | // Initialize this class by calling the super constructor with the given
47 | // value
48 | super(numberOfFields, universe.nilObject);
49 | invokablesTable = new HashMap();
50 | this.universe = universe;
51 | }
52 |
53 | public SObject getSuperClass() {
54 | // Get the super class by reading the field with super class index
55 | return superclass;
56 | }
57 |
58 | public void setSuperClass(final SObject value) {
59 | // Set the super class by writing to the field with super class index
60 | superclass = value;
61 | }
62 |
63 | public boolean hasSuperClass() {
64 | // Check whether or not this class has a super class
65 | return superclass != universe.nilObject;
66 | }
67 |
68 | public SSymbol getName() {
69 | // Get the name of this class by reading the field with name index
70 | return name;
71 | }
72 |
73 | public void setName(final SSymbol value) {
74 | // Set the name of this class by writing to the field with name index
75 | name = value;
76 | }
77 |
78 | public SArray getInstanceFields() {
79 | // Get the instance fields by reading the field with the instance fields
80 | // index
81 | return instanceFields;
82 | }
83 |
84 | public void setInstanceFields(final SArray value) {
85 | // Set the instance fields by writing to the field with the instance
86 | // fields index
87 | instanceFields = value;
88 | }
89 |
90 | public SArray getInstanceInvokables() {
91 | // Get the instance invokables by reading the field with the instance
92 | // invokables index
93 | return instanceInvokables;
94 | }
95 |
96 | public void setInstanceInvokables(final SArray value) {
97 | // Set the instance invokables by writing to the field with the instance
98 | // invokables index
99 | instanceInvokables = value;
100 |
101 | // Make sure this class is the holder of all invokables in the array
102 | for (int i = 0; i < getNumberOfInstanceInvokables(); i++) {
103 | getInstanceInvokable(i).setHolder(this);
104 | }
105 | }
106 |
107 | public int getNumberOfInstanceInvokables() {
108 | // Return the number of instance invokables in this class
109 | return getInstanceInvokables().getNumberOfIndexableFields();
110 | }
111 |
112 | public SInvokable getInstanceInvokable(final int index) {
113 | // Get the instance invokable with the given index
114 | return (SInvokable) getInstanceInvokables().getIndexableField(index);
115 | }
116 |
117 | public void setInstanceInvokable(final int index, final SInvokable value) {
118 | // Set this class as the holder of the given invokable
119 | value.setHolder(this);
120 |
121 | // Set the instance method with the given index to the given value
122 | getInstanceInvokables().setIndexableField(index, (SAbstractObject) value);
123 | }
124 |
125 | @Override
126 | public int getDefaultNumberOfFields() {
127 | // Return the default number of fields in a class
128 | return numberOfClassFields;
129 | }
130 |
131 | public SInvokable lookupInvokable(final SSymbol signature) {
132 | SInvokable invokable;
133 |
134 | // Lookup invokable and return if found
135 | invokable = invokablesTable.get(signature);
136 | if (invokable != null) {
137 | return invokable;
138 | }
139 |
140 | // Lookup invokable with given signature in array of instance invokables
141 | for (int i = 0; i < getNumberOfInstanceInvokables(); i++) {
142 | // Get the next invokable in the instance invokable array
143 | invokable = getInstanceInvokable(i);
144 |
145 | // Return the invokable if the signature matches
146 | if (invokable.getSignature() == signature) {
147 | invokablesTable.put(signature, invokable);
148 | return invokable;
149 | }
150 | }
151 |
152 | // Traverse the super class chain by calling lookup on the super class
153 | if (hasSuperClass()) {
154 | invokable = ((SClass) getSuperClass()).lookupInvokable(signature);
155 | if (invokable != null) {
156 | invokablesTable.put(signature, invokable);
157 | return invokable;
158 | }
159 | }
160 |
161 | // Invokable not found
162 | return null;
163 | }
164 |
165 | public int lookupFieldIndex(final SSymbol fieldName) {
166 | // Lookup field with given name in array of instance fields
167 | for (int i = getNumberOfInstanceFields() - 1; i >= 0; i--) {
168 | // Return the current index if the name matches
169 | if (fieldName == getInstanceFieldName(i)) {
170 | return i;
171 | }
172 | }
173 |
174 | // Field not found
175 | return -1;
176 | }
177 |
178 | public boolean addInstanceInvokable(final SInvokable value) {
179 | // Add the given invokable to the array of instance invokables
180 | for (int i = 0; i < getNumberOfInstanceInvokables(); i++) {
181 | // Get the next invokable in the instance invokable array
182 | SInvokable invokable = getInstanceInvokable(i);
183 |
184 | // Replace the invokable with the given one if the signature matches
185 | if (invokable.getSignature() == value.getSignature()) {
186 | setInstanceInvokable(i, value);
187 | return false;
188 | }
189 | }
190 |
191 | // Append the given method to the array of instance methods
192 | setInstanceInvokables(getInstanceInvokables().copyAndExtendWith(
193 | (SAbstractObject) value, universe));
194 | return true;
195 | }
196 |
197 | public void addInstancePrimitive(final SPrimitive value) {
198 | addInstancePrimitive(value, false);
199 | }
200 |
201 | public void addInstancePrimitive(final SPrimitive value, final boolean suppressWarning) {
202 | if (addInstanceInvokable(value) && !suppressWarning) {
203 | Universe.print("Warning: Primitive " + value.getSignature().getEmbeddedString());
204 | Universe.println(" is not in class definition for class "
205 | + getName().getEmbeddedString());
206 | }
207 | }
208 |
209 | public SSymbol getInstanceFieldName(int index) {
210 | // Get the name of the instance field with the given index
211 | if (index >= getNumberOfSuperInstanceFields()) {
212 | // Adjust the index to account for fields defined in the super class
213 | index -= getNumberOfSuperInstanceFields();
214 |
215 | // Return the symbol representing the instance fields name
216 | return (SSymbol) getInstanceFields().getIndexableField(index);
217 | } else {
218 | // Ask the super class to return the name of the instance field
219 | return ((SClass) getSuperClass()).getInstanceFieldName(index);
220 | }
221 | }
222 |
223 | public int getNumberOfInstanceFields() {
224 | // Get the total number of instance fields in this class
225 | return instanceFields.getNumberOfIndexableFields()
226 | + getNumberOfSuperInstanceFields();
227 | }
228 |
229 | private int getNumberOfSuperInstanceFields() {
230 | // Get the total number of instance fields defined in super classes
231 | if (hasSuperClass()) {
232 | return ((SClass) getSuperClass()).getNumberOfInstanceFields();
233 | } else {
234 | return 0;
235 | }
236 | }
237 |
238 | public boolean hasPrimitives() {
239 | // Lookup invokable with given signature in array of instance invokables
240 | for (int i = 0; i < getNumberOfInstanceInvokables(); i++) {
241 | // Get the next invokable in the instance invokable array
242 | if (getInstanceInvokable(i).isPrimitive()) {
243 | return true;
244 | }
245 | }
246 | return false;
247 | }
248 |
249 | public void loadPrimitives() {
250 | // Compute the class name of the Java(TM) class containing the
251 | // primitives
252 | String className = "som.primitives." + getName().getEmbeddedString()
253 | + "Primitives";
254 |
255 | // Try loading the primitives
256 | try {
257 | Class> primitivesClass = Class.forName(className);
258 | try {
259 | Constructor> ctor = primitivesClass.getConstructor(Universe.class);
260 | ((Primitives) ctor.newInstance(universe)).installPrimitivesIn(this);
261 | } catch (Exception e) {
262 | Universe.println("Primitives class " + className
263 | + " cannot be instantiated");
264 | }
265 | } catch (ClassNotFoundException e) {
266 | Universe.println("Primitives class " + className + " not found");
267 | }
268 | }
269 |
270 | @Override
271 | public String toString() {
272 | return "Class(" + getName().getEmbeddedString() + ")";
273 | }
274 |
275 | // Implementation specific fields
276 | private SObject superclass;
277 | private SSymbol name;
278 | private SArray instanceInvokables;
279 | private SArray instanceFields;
280 |
281 | // Mapping of symbols to invokables
282 | private final HashMap invokablesTable;
283 |
284 | // Static field indices and number of class fields
285 | static final int numberOfClassFields = numberOfObjectFields;
286 | }
287 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SDouble.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.vmobjects;
26 |
27 | import som.vm.Universe;
28 |
29 |
30 | public final class SDouble extends SNumber {
31 |
32 | private final double embeddedDouble;
33 |
34 | public SDouble(final double value) {
35 | embeddedDouble = value;
36 | }
37 |
38 | public double getEmbeddedDouble() {
39 | // Get the embedded double
40 | return embeddedDouble;
41 | }
42 |
43 | @Override
44 | public String toString() {
45 | return super.toString() + "(" + embeddedDouble + ")";
46 | }
47 |
48 | @Override
49 | public SClass getSOMClass(final Universe universe) {
50 | return universe.doubleClass;
51 | }
52 |
53 | private double coerceToDouble(final SNumber o, final Universe universe) {
54 | if (o instanceof SDouble) {
55 | return ((SDouble) o).embeddedDouble;
56 | }
57 | if (o instanceof SInteger) {
58 | return ((SInteger) o).getEmbeddedInteger();
59 | }
60 | if (o instanceof SBigInteger) {
61 | return ((SBigInteger) o).getEmbeddedBiginteger().doubleValue();
62 | }
63 | throw new ClassCastException("Cannot coerce to Double!");
64 | }
65 |
66 | @Override
67 | public SString primAsString(final Universe universe) {
68 | return universe.newString(Double.toString(embeddedDouble));
69 | }
70 |
71 | @Override
72 | public SDouble primAsDouble(final Universe universe) {
73 | return this;
74 | }
75 |
76 | public SInteger primAsInteger(final Universe universe) {
77 | return universe.newInteger((long) embeddedDouble);
78 | }
79 |
80 | @Override
81 | public SNumber primSqrt(final Universe universe) {
82 | return universe.newDouble(Math.sqrt(embeddedDouble));
83 | }
84 |
85 | @Override
86 | public SNumber primAdd(final SNumber right, final Universe universe) {
87 | double r = coerceToDouble(right, universe);
88 | return universe.newDouble(embeddedDouble + r);
89 | }
90 |
91 | @Override
92 | public SNumber primSubtract(final SNumber right, final Universe universe) {
93 | double r = coerceToDouble(right, universe);
94 | return universe.newDouble(embeddedDouble - r);
95 | }
96 |
97 | @Override
98 | public SNumber primMultiply(final SNumber right, final Universe universe) {
99 | double r = coerceToDouble(right, universe);
100 | return universe.newDouble(embeddedDouble * r);
101 | }
102 |
103 | @Override
104 | public SNumber primDoubleDivide(final SNumber right, final Universe universe) {
105 | double r = coerceToDouble(right, universe);
106 | return universe.newDouble(embeddedDouble / r);
107 | }
108 |
109 | @Override
110 | public SNumber primIntegerDivide(final SNumber right, final Universe universe) {
111 | throw new RuntimeException("not yet implemented, SOM doesn't offer it");
112 | }
113 |
114 | @Override
115 | public SNumber primModulo(final SNumber right, final Universe universe) {
116 | double r = coerceToDouble(right, universe);
117 | return universe.newDouble(embeddedDouble % r);
118 | }
119 |
120 | @Override
121 | public SNumber primBitAnd(final SNumber right, final Universe universe) {
122 | throw new RuntimeException("Not supported for doubles");
123 | }
124 |
125 | @Override
126 | public SNumber primBitXor(final SNumber right, final Universe universe) {
127 | throw new RuntimeException("Not supported for doubles");
128 | }
129 |
130 | @Override
131 | public SNumber primLeftShift(final SNumber right, final Universe universe) {
132 | throw new RuntimeException("Not supported for doubles");
133 | }
134 |
135 | @Override
136 | public SObject primEqual(final SAbstractObject right, final Universe universe) {
137 | if (!(right instanceof SNumber)) {
138 | return universe.falseObject;
139 | }
140 |
141 | double r = coerceToDouble((SNumber) right, universe);
142 | return asSBoolean(embeddedDouble == r, universe);
143 | }
144 |
145 | @Override
146 | public SObject primLessThan(final SNumber right, final Universe universe) {
147 | double r = coerceToDouble(right, universe);
148 | return asSBoolean(embeddedDouble < r, universe);
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SInteger.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2016 Michael Haupt, github@haupz.de
3 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
4 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
5 | * http://www.hpi.uni-potsdam.de/swa/
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package som.vmobjects;
27 |
28 | import java.math.BigInteger;
29 | import java.util.HashMap;
30 | import java.util.Map;
31 |
32 | import som.vm.Universe;
33 |
34 |
35 | public final class SInteger extends SNumber {
36 |
37 | /**
38 | * Language convention requires integers up to this value to be identical.
39 | */
40 | private static final long MAX_IDENTICAL_INT = 1073741823L;
41 |
42 | /**
43 | * Cache to store integers up to {@link #MAX_IDENTICAL_INT}.
44 | */
45 | private static Map CACHE = new HashMap<>();
46 |
47 | // Private variable holding the embedded integer
48 | private final long embeddedInteger;
49 |
50 | private SInteger(final long value) {
51 | embeddedInteger = value;
52 | }
53 |
54 | public static SInteger getInteger(final long value) {
55 | if (value > MAX_IDENTICAL_INT) {
56 | return new SInteger(value);
57 | }
58 | return CACHE.computeIfAbsent(value, SInteger::new);
59 | }
60 |
61 | public long getEmbeddedInteger() {
62 | // Get the embedded integer
63 | return embeddedInteger;
64 | }
65 |
66 | @Override
67 | public String toString() {
68 | return super.toString() + "(" + embeddedInteger + ")";
69 | }
70 |
71 | @Override
72 | public SClass getSOMClass(final Universe universe) {
73 | return universe.integerClass;
74 | }
75 |
76 | @Override
77 | public SString primAsString(final Universe universe) {
78 | return universe.newString(Long.toString(embeddedInteger));
79 | }
80 |
81 | @Override
82 | public SNumber primAsDouble(final Universe universe) {
83 | return universe.newDouble(embeddedInteger);
84 | }
85 |
86 | @Override
87 | public SNumber primSqrt(final Universe universe) {
88 | double result = Math.sqrt(embeddedInteger);
89 |
90 | if (result == Math.rint(result)) {
91 | return intOrBigInt(result, universe);
92 | } else {
93 | return universe.newDouble(result);
94 | }
95 | }
96 |
97 | @Override
98 | public SNumber primAdd(final SNumber right, final Universe universe) {
99 | if (right instanceof SBigInteger) {
100 | BigInteger result = BigInteger.valueOf(embeddedInteger).add(
101 | ((SBigInteger) right).getEmbeddedBiginteger());
102 | return universe.newBigInteger(result);
103 | } else if (right instanceof SDouble) {
104 | double result = embeddedInteger + ((SDouble) right).getEmbeddedDouble();
105 | return universe.newDouble(result);
106 | } else {
107 | SInteger r = (SInteger) right;
108 |
109 | try {
110 | long result = Math.addExact(embeddedInteger, r.getEmbeddedInteger());
111 | return universe.newInteger(result);
112 | } catch (ArithmeticException e) {
113 | BigInteger result = BigInteger.valueOf(embeddedInteger).add(
114 | BigInteger.valueOf(r.getEmbeddedInteger()));
115 | return universe.newBigInteger(result);
116 | }
117 | }
118 | }
119 |
120 | @Override
121 | public SNumber primSubtract(final SNumber right, final Universe universe) {
122 | if (right instanceof SBigInteger) {
123 | BigInteger result = BigInteger.valueOf(embeddedInteger).subtract(
124 | ((SBigInteger) right).getEmbeddedBiginteger());
125 | return universe.newBigInteger(result);
126 | } else if (right instanceof SDouble) {
127 | double result = embeddedInteger - ((SDouble) right).getEmbeddedDouble();
128 | return universe.newDouble(result);
129 | } else {
130 | SInteger r = (SInteger) right;
131 |
132 | try {
133 | long result = Math.subtractExact(embeddedInteger, r.getEmbeddedInteger());
134 | return universe.newInteger(result);
135 | } catch (ArithmeticException e) {
136 | BigInteger result = BigInteger.valueOf(embeddedInteger).subtract(
137 | BigInteger.valueOf(r.getEmbeddedInteger()));
138 | return universe.newBigInteger(result);
139 | }
140 | }
141 | }
142 |
143 | @Override
144 | public SNumber primMultiply(final SNumber right, final Universe universe) {
145 | if (right instanceof SBigInteger) {
146 | BigInteger result = BigInteger.valueOf(embeddedInteger).multiply(
147 | ((SBigInteger) right).getEmbeddedBiginteger());
148 | return universe.newBigInteger(result);
149 | } else if (right instanceof SDouble) {
150 | double result = embeddedInteger * ((SDouble) right).getEmbeddedDouble();
151 | return universe.newDouble(result);
152 | } else {
153 | SInteger r = (SInteger) right;
154 |
155 | try {
156 | long result = Math.multiplyExact(embeddedInteger, r.getEmbeddedInteger());
157 | return universe.newInteger(result);
158 | } catch (ArithmeticException e) {
159 | BigInteger result = BigInteger.valueOf(embeddedInteger).multiply(
160 | BigInteger.valueOf(r.getEmbeddedInteger()));
161 | return universe.newBigInteger(result);
162 | }
163 | }
164 | }
165 |
166 | @Override
167 | public SNumber primDoubleDivide(final SNumber right, final Universe universe) {
168 | double result;
169 |
170 | if (right instanceof SBigInteger) {
171 | result = embeddedInteger / ((SBigInteger) right).getEmbeddedBiginteger().doubleValue();
172 | } else if (right instanceof SDouble) {
173 | result = embeddedInteger / ((SDouble) right).getEmbeddedDouble();
174 | } else {
175 | result = (double) embeddedInteger / ((SInteger) right).getEmbeddedInteger();
176 | }
177 |
178 | return universe.newDouble(result);
179 | }
180 |
181 | @Override
182 | public SNumber primIntegerDivide(final SNumber right, final Universe universe) {
183 | if (right instanceof SBigInteger) {
184 | BigInteger result = BigInteger.valueOf(embeddedInteger).divide(
185 | ((SBigInteger) right).getEmbeddedBiginteger());
186 | return universe.newBigInteger(result);
187 | } else if (right instanceof SDouble) {
188 | long result = (long) (embeddedInteger / ((SDouble) right).getEmbeddedDouble());
189 | return universe.newInteger(result);
190 | } else {
191 | long result = embeddedInteger / ((SInteger) right).getEmbeddedInteger();
192 | return universe.newInteger(result);
193 | }
194 | }
195 |
196 | @Override
197 | public SNumber primModulo(final SNumber right, final Universe universe) {
198 | if (right instanceof SBigInteger) {
199 | // Note: modulo semantics of SOM differ from Java, with respect to
200 | // negative operands, but BigInteger doesn't support a negative
201 | // second operand, so, we should get an exception, which we can
202 | // properly handle once an application actually needs it.
203 | BigInteger result = BigInteger.valueOf(embeddedInteger).mod(
204 | ((SBigInteger) right).getEmbeddedBiginteger());
205 | return universe.newBigInteger(result);
206 | } else if (right instanceof SDouble) {
207 | double result = embeddedInteger % ((SDouble) right).getEmbeddedDouble();
208 | return universe.newDouble(result);
209 | } else {
210 | long r = ((SInteger) right).getEmbeddedInteger();
211 | long result = Math.floorMod(embeddedInteger, r);
212 | return universe.newInteger(result);
213 | }
214 | }
215 |
216 | public SInteger primRemainder(final SNumber right, final Universe universe) {
217 | if (right instanceof SInteger) {
218 | return universe.newInteger(embeddedInteger % ((SInteger) right).embeddedInteger);
219 | } else {
220 | throw new RuntimeException("TODO");
221 | }
222 | }
223 |
224 | @Override
225 | public SNumber primBitAnd(final SNumber right, final Universe universe) {
226 | if (right instanceof SBigInteger) {
227 | BigInteger result = BigInteger.valueOf(embeddedInteger).and(
228 | ((SBigInteger) right).getEmbeddedBiginteger());
229 | return universe.newBigInteger(result);
230 | } else {
231 | long result = embeddedInteger & ((SInteger) right).embeddedInteger;
232 | return universe.newInteger(result);
233 | }
234 | }
235 |
236 | @Override
237 | public SNumber primBitXor(final SNumber right, final Universe universe) {
238 | if (right instanceof SBigInteger) {
239 | BigInteger result = BigInteger.valueOf(embeddedInteger).xor(
240 | ((SBigInteger) right).getEmbeddedBiginteger());
241 | return universe.newBigInteger(result);
242 | } else {
243 | long result = embeddedInteger ^ ((SInteger) right).embeddedInteger;
244 | return universe.newInteger(result);
245 | }
246 | }
247 |
248 | @Override
249 | public SNumber primLeftShift(final SNumber right, final Universe universe) {
250 | long r = ((SInteger) right).embeddedInteger;
251 | assert r > 0;
252 |
253 | if (Long.SIZE - Long.numberOfLeadingZeros(embeddedInteger) + r > Long.SIZE - 1) {
254 | BigInteger result = BigInteger.valueOf(embeddedInteger).shiftLeft((int) r);
255 | return universe.newBigInteger(result);
256 | }
257 |
258 | long result = embeddedInteger << r;
259 | return universe.newInteger(result);
260 | }
261 |
262 | @Override
263 | public SObject primEqual(final SAbstractObject right, final Universe universe) {
264 | boolean result;
265 |
266 | if (right instanceof SBigInteger) {
267 | result = BigInteger.valueOf(embeddedInteger).equals(
268 | ((SBigInteger) right).getEmbeddedBiginteger());
269 | } else if (right instanceof SDouble) {
270 | result = embeddedInteger == ((SDouble) right).getEmbeddedDouble();
271 | } else if (right instanceof SInteger) {
272 | result = embeddedInteger == ((SInteger) right).getEmbeddedInteger();
273 | } else {
274 | result = false;
275 | }
276 |
277 | return asSBoolean(result, universe);
278 | }
279 |
280 | @Override
281 | public SObject primLessThan(final SNumber right, final Universe universe) {
282 | boolean result;
283 | if (right instanceof SBigInteger) {
284 | result = BigInteger.valueOf(embeddedInteger).compareTo(
285 | ((SBigInteger) right).getEmbeddedBiginteger()) < 0;
286 | } else if (right instanceof SDouble) {
287 | result = embeddedInteger < ((SDouble) right).getEmbeddedDouble();
288 | } else {
289 | result = embeddedInteger < ((SInteger) right).getEmbeddedInteger();
290 | }
291 |
292 | return asSBoolean(result, universe);
293 | }
294 | }
295 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SInvokable.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.vmobjects;
26 |
27 | import som.interpreter.Frame;
28 | import som.interpreter.Interpreter;
29 |
30 |
31 | public interface SInvokable {
32 |
33 | // Tells whether this is a primitive
34 | boolean isPrimitive();
35 |
36 | // Invoke this invokable object in a given frame
37 | void invoke(Frame frame, Interpreter interpreter);
38 |
39 | // Get the signature for this invokable object
40 | SSymbol getSignature();
41 |
42 | // Get the holder for this invokable object
43 | SClass getHolder();
44 |
45 | // Set the holder for this invokable object
46 | void setHolder(SClass value);
47 | }
48 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SMethod.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.vmobjects;
26 |
27 | import java.util.List;
28 |
29 | import som.interpreter.Frame;
30 | import som.interpreter.Interpreter;
31 | import som.vm.Universe;
32 |
33 |
34 | public class SMethod extends SAbstractObject implements SInvokable {
35 |
36 | public SMethod(final SSymbol signature, final int numberOfBytecodes,
37 | final int numberOfLocals, final int maxNumStackElements,
38 | final List literals) {
39 | this.signature = signature;
40 | this.numberOfLocals = numberOfLocals;
41 | this.bytecodes = new byte[numberOfBytecodes];
42 | inlineCacheClass = new SClass[numberOfBytecodes];
43 | inlineCacheInvokable = new SInvokable[numberOfBytecodes];
44 | maximumNumberOfStackElements = maxNumStackElements;
45 | this.literals =
46 | literals == null ? null : literals.toArray(new SAbstractObject[literals.size()]);
47 | }
48 |
49 | @Override
50 | public boolean isPrimitive() {
51 | return false;
52 | }
53 |
54 | public int getNumberOfLocals() {
55 | return numberOfLocals;
56 | }
57 |
58 | public int getMaximumNumberOfStackElements() {
59 | return maximumNumberOfStackElements;
60 | }
61 |
62 | @Override
63 | public SSymbol getSignature() {
64 | return signature;
65 | }
66 |
67 | @Override
68 | public SClass getHolder() {
69 | return holder;
70 | }
71 |
72 | @Override
73 | public void setHolder(final SClass value) {
74 | holder = value;
75 |
76 | if (literals == null) {
77 | return;
78 | }
79 |
80 | // Make sure all nested invokables have the same holder
81 | for (int i = 0; i < literals.length; i++) {
82 | if (literals[i] instanceof SInvokable) {
83 | ((SInvokable) literals[i]).setHolder(value);
84 | }
85 | }
86 | }
87 |
88 | public SAbstractObject getConstant(final int bytecodeIndex) {
89 | // Get the constant associated to a given bytecode index
90 | return literals[bytecodes[bytecodeIndex + 1]];
91 | }
92 |
93 | public int getNumberOfArguments() {
94 | // Get the number of arguments of this method
95 | return getSignature().getNumberOfSignatureArguments();
96 | }
97 |
98 | public int getNumberOfBytecodes() {
99 | // Get the number of bytecodes in this method
100 | return bytecodes.length;
101 | }
102 |
103 | public byte getBytecode(final int index) {
104 | // Get the bytecode at the given index
105 | return bytecodes[index];
106 | }
107 |
108 | public void setBytecode(final int index, final byte value) {
109 | // Set the bytecode at the given index to the given value
110 | bytecodes[index] = value;
111 | }
112 |
113 | @Override
114 | public void invoke(final Frame frame, final Interpreter interpreter) {
115 | // Allocate and push a new frame on the interpreter stack
116 | Frame newFrame = interpreter.pushNewFrame(this);
117 | newFrame.copyArgumentsFrom(frame);
118 | }
119 |
120 | @Override
121 | public String toString() {
122 | return "Method(" + getHolder().getName().getEmbeddedString() + ">>"
123 | + getSignature().toString() + ")";
124 | }
125 |
126 | public SClass getInlineCacheClass(final int bytecodeIndex) {
127 | return inlineCacheClass[bytecodeIndex];
128 | }
129 |
130 | public SInvokable getInlineCacheInvokable(final int bytecodeIndex) {
131 | return inlineCacheInvokable[bytecodeIndex];
132 | }
133 |
134 | public void setInlineCache(final int bytecodeIndex, final SClass receiverClass,
135 | final SInvokable invokable) {
136 | inlineCacheClass[bytecodeIndex] = receiverClass;
137 | inlineCacheInvokable[bytecodeIndex] = invokable;
138 | }
139 |
140 | @Override
141 | public SClass getSOMClass(final Universe universe) {
142 | return universe.methodClass;
143 | }
144 |
145 | // Private variable holding byte array of bytecodes
146 | private final byte[] bytecodes;
147 | private final SClass[] inlineCacheClass;
148 | private final SInvokable[] inlineCacheInvokable;
149 |
150 | private final SAbstractObject[] literals;
151 |
152 | private final SSymbol signature;
153 | private SClass holder;
154 |
155 | // Meta information
156 | private final int numberOfLocals;
157 | private final int maximumNumberOfStackElements;
158 | }
159 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SNumber.java:
--------------------------------------------------------------------------------
1 | package som.vmobjects;
2 |
3 | import java.math.BigInteger;
4 |
5 | import som.vm.Universe;
6 |
7 |
8 | public abstract class SNumber extends SAbstractObject {
9 | public abstract SString primAsString(Universe universe);
10 |
11 | public abstract SNumber primAsDouble(Universe universe);
12 |
13 | public abstract SNumber primSqrt(Universe universe);
14 |
15 | public abstract SNumber primAdd(SNumber right, Universe universe);
16 |
17 | public abstract SNumber primSubtract(SNumber right, Universe universe);
18 |
19 | public abstract SNumber primMultiply(SNumber right, Universe universe);
20 |
21 | public abstract SNumber primDoubleDivide(SNumber right, Universe universe);
22 |
23 | public abstract SNumber primIntegerDivide(SNumber right, Universe universe);
24 |
25 | public abstract SNumber primModulo(SNumber right, Universe universe);
26 |
27 | public abstract SNumber primBitAnd(SNumber right, Universe universe);
28 |
29 | public abstract SNumber primBitXor(SNumber right, Universe universe);
30 |
31 | public abstract SNumber primLeftShift(SNumber right, Universe universe);
32 |
33 | public abstract SObject primEqual(SAbstractObject right, Universe universe);
34 |
35 | public abstract SObject primLessThan(SNumber right, Universe universe);
36 |
37 | protected final SNumber intOrBigInt(final double value, final Universe universe) {
38 | if (value > Long.MAX_VALUE || value < Long.MIN_VALUE) {
39 | return universe.newBigInteger(new BigInteger(Double.toString(Math.rint(value))));
40 | } else {
41 | return universe.newInteger((long) Math.rint(value));
42 | }
43 | }
44 |
45 | protected final SObject asSBoolean(final boolean result, final Universe universe) {
46 | if (result) {
47 | return universe.trueObject;
48 | } else {
49 | return universe.falseObject;
50 | }
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SObject.java:
--------------------------------------------------------------------------------
1 | package som.vmobjects;
2 |
3 | import som.vm.Universe;
4 |
5 |
6 | public class SObject extends SAbstractObject {
7 |
8 | public SObject(final SObject nilObject) {
9 | fields = new SAbstractObject[getDefaultNumberOfFields()];
10 |
11 | // Clear each and every field by putting nil into them
12 | for (int i = 0; i < getNumberOfFields(); i++) {
13 | setField(i, nilObject);
14 | }
15 | }
16 |
17 | public SObject(final int numberOfFields, final SObject nilObject) {
18 | fields = new SAbstractObject[numberOfFields];
19 |
20 | // Clear each and every field by putting nil into them
21 | for (int i = 0; i < getNumberOfFields(); i++) {
22 | setField(i, nilObject);
23 | }
24 | }
25 |
26 | public SClass getSOMClass() {
27 | return clazz;
28 | }
29 |
30 | public void setClass(final SClass value) {
31 | // Set the class of this object by writing to the field with class index
32 | clazz = value;
33 | }
34 |
35 | public SSymbol getFieldName(final int index) {
36 | // Get the name of the field with the given index
37 | return getSOMClass().getInstanceFieldName(index);
38 | }
39 |
40 | public int getFieldIndex(final SSymbol name) {
41 | // Get the index for the field with the given name
42 | return getSOMClass().lookupFieldIndex(name);
43 | }
44 |
45 | public int getNumberOfFields() {
46 | // Get the number of fields in this object
47 | return fields.length;
48 | }
49 |
50 | public int getDefaultNumberOfFields() {
51 | // Return the default number of fields in an object
52 | return numberOfObjectFields;
53 | }
54 |
55 | public SAbstractObject getField(final long index) {
56 | // Get the field with the given index
57 | return fields[(int) index];
58 | }
59 |
60 | public void setField(final long index, final SAbstractObject value) {
61 | // Set the field with the given index to the given value
62 | fields[(int) index] = value;
63 | }
64 |
65 | @Override
66 | public SClass getSOMClass(final Universe universe) {
67 | return clazz;
68 | }
69 |
70 | @Override
71 | public String toString() {
72 | if (clazz.getName().getEmbeddedString().equals("SObject")) {
73 | if (fields[1] instanceof SObject) {
74 | SObject somClazz = (SObject) fields[1];
75 | SObject nameSymbolObj = (SObject) somClazz.fields[4];
76 | SString nameString = (SString) nameSymbolObj.fields[0];
77 | return "SomSom: a " + nameString.getEmbeddedString();
78 | }
79 | }
80 | return "a " + getSOMClass(Universe.current()).getName().getEmbeddedString();
81 | }
82 |
83 | // Private array of fields
84 | private final SAbstractObject[] fields;
85 | private SClass clazz;
86 |
87 | // Static field indices and number of object fields
88 | static final int numberOfObjectFields = 0;
89 | }
90 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SPrimitive.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2013 Stefan Marr, stefan.marr@vub.ac.be
3 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
4 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
5 | * http://www.hpi.uni-potsdam.de/swa/
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package som.vmobjects;
27 |
28 | import som.interpreter.Frame;
29 | import som.interpreter.Interpreter;
30 | import som.vm.Universe;
31 |
32 |
33 | public abstract class SPrimitive extends SAbstractObject implements SInvokable {
34 |
35 | @Override
36 | public boolean isPrimitive() {
37 | return true;
38 | }
39 |
40 | public SPrimitive(String signatureString, final Universe universe) {
41 | signature = universe.symbolFor(signatureString);
42 | }
43 |
44 | @Override
45 | public SSymbol getSignature() {
46 | return signature;
47 | }
48 |
49 | @Override
50 | public SClass getHolder() {
51 | return holder;
52 | }
53 |
54 | @Override
55 | public void setHolder(SClass value) {
56 | holder = value;
57 | }
58 |
59 | public boolean isEmpty() {
60 | // By default a primitive is not empty
61 | return false;
62 | }
63 |
64 | @Override
65 | public SClass getSOMClass(final Universe universe) {
66 | return universe.primitiveClass;
67 | }
68 |
69 | public static SPrimitive getEmptyPrimitive(java.lang.String signatureString,
70 | final Universe universe) {
71 | // Return an empty primitive with the given signature
72 | return (new SPrimitive(signatureString, universe) {
73 |
74 | @Override
75 | public void invoke(final Frame frame, final Interpreter interpreter) {
76 | // Write a warning to the screen
77 | Universe.println("Warning: undefined primitive "
78 | + this.getSignature().getEmbeddedString() + " called");
79 | }
80 |
81 | @Override
82 | public boolean isEmpty() {
83 | // The empty primitives are empty
84 | return true;
85 | }
86 | });
87 | }
88 |
89 | private final SSymbol signature;
90 | private SClass holder;
91 | }
92 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SString.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.vmobjects;
26 |
27 | import som.vm.Universe;
28 |
29 |
30 | public class SString extends SAbstractObject {
31 |
32 | public SString(final String value) {
33 | string = value;
34 | }
35 |
36 | public String getEmbeddedString() {
37 | return string;
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return "\"" + string + "\"";
43 | }
44 |
45 | @Override
46 | public SClass getSOMClass(final Universe universe) {
47 | return universe.stringClass;
48 | }
49 |
50 | // Private variable holding the string associated to this symbol
51 | private final String string;
52 | }
53 |
--------------------------------------------------------------------------------
/src/som/vmobjects/SSymbol.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de
3 | * Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany
4 | * http://www.hpi.uni-potsdam.de/swa/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package som.vmobjects;
26 |
27 | import som.compiler.Lexer;
28 | import som.vm.Universe;
29 |
30 |
31 | public class SSymbol extends SString {
32 |
33 | public SSymbol(final String value) {
34 | super(value);
35 | numberOfSignatureArguments = determineNumberOfSignatureArguments();
36 | }
37 |
38 | private int determineNumberOfSignatureArguments() {
39 | // Check for binary signature
40 | if (isBinarySignature()) {
41 | return 2;
42 | } else {
43 | // Count the colons in the signature string
44 | int numberOfColons = 0;
45 |
46 | // Iterate through every character in the signature string
47 | for (char c : getEmbeddedString().toCharArray()) {
48 | if (c == ':') {
49 | numberOfColons++;
50 | }
51 | }
52 |
53 | // The number of arguments is equal to the number of colons plus one
54 | return numberOfColons + 1;
55 | }
56 | }
57 |
58 | @Override
59 | public String toString() {
60 | return "#" + getEmbeddedString();
61 | }
62 |
63 | public int getNumberOfSignatureArguments() {
64 | return numberOfSignatureArguments;
65 | }
66 |
67 | public boolean isBinarySignature() {
68 | // Check the individual characters of the string
69 | for (char c : getEmbeddedString().toCharArray()) {
70 | if (!Lexer.isOperator(c)) {
71 | return false;
72 | }
73 | }
74 | return true;
75 | }
76 |
77 | @Override
78 | public SClass getSOMClass(final Universe universe) {
79 | return universe.symbolClass;
80 | }
81 |
82 | private final int numberOfSignatureArguments;
83 | }
84 |
--------------------------------------------------------------------------------
/tests/som/compiler/LexerTests.java:
--------------------------------------------------------------------------------
1 | package som.compiler;
2 |
3 | import static org.junit.Assert.assertEquals;
4 |
5 | import java.io.StringReader;
6 |
7 | import org.junit.Test;
8 |
9 |
10 | /**
11 | * A small set of tests for the SOM lexer to demonstrate it's basic functionality.
12 | */
13 | public class LexerTests {
14 | @Test
15 | public void emptyClass() {
16 | Lexer l = new Lexer(new StringReader("Foo = ()"));
17 |
18 | assertEquals(Symbol.Identifier, l.getSym());
19 | assertEquals("Foo", l.getText());
20 |
21 | assertEquals(Symbol.Equal, l.getSym());
22 | assertEquals("=", l.getText());
23 |
24 | assertEquals(Symbol.NewTerm, l.getSym());
25 | assertEquals("(", l.getText());
26 |
27 | assertEquals(Symbol.EndTerm, l.getSym());
28 | assertEquals(")", l.getText());
29 |
30 | assertEquals(Symbol.NONE, l.getSym());
31 | }
32 |
33 | @Test
34 | public void keywordSymbol() {
35 | Lexer l = new Lexer(new StringReader("#key:word:"));
36 |
37 | assertEquals(Symbol.Pound, l.getSym());
38 | assertEquals("#", l.getText());
39 |
40 | assertEquals(Symbol.KeywordSequence, l.getSym());
41 | assertEquals("key:word:", l.getText());
42 |
43 | assertEquals(Symbol.NONE, l.getSym());
44 | }
45 |
46 | @Test
47 | public void assignDouble() {
48 | Lexer l = new Lexer(new StringReader("var := 3.14."));
49 |
50 | assertEquals(Symbol.Identifier, l.getSym());
51 | assertEquals("var", l.getText());
52 |
53 | assertEquals(Symbol.Assign, l.getSym());
54 | assertEquals(":=", l.getText());
55 |
56 | assertEquals(Symbol.Double, l.getSym());
57 | assertEquals("3.14", l.getText());
58 |
59 | assertEquals(Symbol.Period, l.getSym());
60 | assertEquals(".", l.getText());
61 |
62 | assertEquals(Symbol.NONE, l.getSym());
63 | }
64 |
65 | @Test
66 | public void string() {
67 | Lexer l = new Lexer(new StringReader("'some string with new\nline'"));
68 |
69 | assertEquals(Symbol.STString, l.getSym());
70 | assertEquals("some string with new\nline", l.getText());
71 |
72 | assertEquals(Symbol.NONE, l.getSym());
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/tests/som/tests/BasicInterpreterTests.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2013 Stefan Marr, stefan.marr@vub.ac.be
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 | package som.tests;
23 |
24 | import static org.junit.Assert.assertEquals;
25 | import static org.junit.Assert.fail;
26 |
27 | import java.util.Arrays;
28 |
29 | import org.junit.Test;
30 | import org.junit.runner.RunWith;
31 | import org.junit.runners.Parameterized;
32 | import org.junit.runners.Parameterized.Parameters;
33 |
34 | import som.compiler.ProgramDefinitionError;
35 | import som.vm.Universe;
36 | import som.vmobjects.SClass;
37 | import som.vmobjects.SDouble;
38 | import som.vmobjects.SInteger;
39 | import som.vmobjects.SSymbol;
40 |
41 |
42 | @RunWith(Parameterized.class)
43 | public class BasicInterpreterTests {
44 |
45 | @Parameters(name = "{0}.{1} [{index}]")
46 | public static Iterable