Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added initial specification of addition and subtraction of integers #61

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
Smalltalk/SOMCore.csp

specification/*.class
specification/*.java
specification/*.tokens
specification/*.interp
specification/are-we-fast-yet
specification/*.jar
/SOM
11 changes: 10 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
name: ykSOM
dist: bionic
rust: [nightly]
env: REPO=yksom.git BUILD="cargo build" SOM="cargo run -- " SOM_TESTS="--cp ../Smalltalk ../TestSuite/TestHarness.som"
env: REPO=yksom.git BUILD="cargo build" SOM="cargo run -- " SOM_TESTS="--cp ../Smalltalk ../TestSuite/TestHarness.som" SOM_SPECS="--cp ../Smalltalk:../TestSuite:../specification/executable_specs ../specification/executable_specs/AllSpecs.som"


# allow_failures:
Expand Down Expand Up @@ -105,4 +105,13 @@ script:

echo "$SOM $SOM_TESTS"
eval "$SOM $SOM_TESTS"

echo Run Specs
if [ "$SOM_SPECS" == "" ]
then
export SOM_SPECS="-cp ../Smalltalk:../TestSuite:../specification/executable_specs AllSpecs"
fi

echo "$SOM $SOM_SPECS"
eval "$SOM $SOM_SPECS"
fi
10 changes: 10 additions & 0 deletions Smalltalk/Object.som
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,14 @@ Object = nil (
instVarAt: idx put: obj = primitive
instVarNamed: sym = primitive

isKindOf: class = (
| superclass |
self class == class ifTrue: [ ^ true ].


[(superclass := self class superclass) == nil] whileFalse: [
superclass == class ifTrue: [ ^ true ] ].

^ false
)
)
20 changes: 17 additions & 3 deletions TestSuite/TestHarness.som
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,29 @@ TestHarness = (
)

runOneSuite: name = (
| testName runner |
| testName runner totalTestNum successfulTestNum unsupportedTestNum totalAssertionNum |
testName := name.
(testName endsWith: 'Test') ifFalse: [
((testName endsWith: 'Test') or: [testName endsWith: 'Spec']) ifFalse: [
testName := testName + 'Test'].

runner := TestRunner new.
runner initializeOn: (system resolve: testName asSymbol).
runner run.
runner hasFailures ifTrue: [system exit: 1]

totalTestNum := runner expectedPasses.
unsupportedTestNum := runner actualUnsupported.
successfulTestNum := runner actualPasses.
totalAssertionNum := runner numAsserts.

'Number of unsupported optionals: ' print.
unsupportedTestNum println.
'Number of assertions tested: ' print.
totalAssertionNum println.

(failOnUnsupportedOptionals and: [unsupportedTestNum > 0])
ifTrue: [system exit: 1].
totalTestNum = successfulTestNum
ifFalse: [system exit: 1].
)

run: args = (
Expand Down
9 changes: 9 additions & 0 deletions specification/executable_specs/AllSpecs.som
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
AllSpecs = TestHarness (
tests = (
| l1 |
l1 := Vector new.
l1 append: IntSpec.
^ l1
)

)
24,222 changes: 24,222 additions & 0 deletions specification/executable_specs/IntSpec.som

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions specification/executable_specs/Specification.som
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Specification = TestCase (

expect: actual toEqual: expected = (
self assert: expected = actual
description: [self comparingStringBetween: expected and: actual]
)

expect: actual toBe: expected = (
self assert: actual == expected
description: [self comparingStringBetween: expected and: actual]
)

expect: actual toEqual: double within: epsilon = (
self assert: double - actual < epsilon
description: ['Expected ' + actual asString + ' to equal ' + double asString + ' within: ' + epsilon asString]
)

expect: actual toBeGreaterThan: expected = (
self assert: actual > expected
description: ['Expected ' + actual asString + ' to be greater than ' + expected]
)

expect: actual toBeKindOf: class = (
self assert: (actual isKindOf: class)
description: ['Expected ' + actual asString + ' to be of class ' + class asString]
)
)
96 changes: 96 additions & 0 deletions specification/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Simple Object Machine

## Language Specification

### Introduction

[SOM][SOM-st] is a minimal Smalltalk dialect which was used to teach VM
construction at the [Hasso Plattner Institute][SOM]. It was originally built at
the University of Århus (Denmark) for teaching.

Currently, SOM is maintained as a research and teaching tool and has its home
at: [https://som-st.github.io][SOM-st]


### Core Library

#### Integer Class

Integers in SOM have arbitrary precision, which means they are not strictly
word-sized or indeed have any other upper limited than the available memory.

All integers are an instance of class `Integer`.

In the following, we define all operations on `Integer`.

##### Addition

The addition of arbitrary-precision integers returns an arbitrary-precision
integer.

For example:

```{spec IntSpec.intAddition}
3 + 4 = 7.
-4 + 3 = -1.
```

The addition of a `Double` value to an integer results in a `Double` value.

For example:

```{spec IntSpec.doubleAddition}
self expect: 3 + 4.4 toEqual: 7.4 within: 0.00000001.
self expect: -4 + 3.3 toEqual: -0.7 within: 0.00000001.
```

Furthermore, the following should hold for `int` being any integer value:

```{spec IntSpec.intAddIncreases, int=allIntVals}
int + 1 > int.
self expect: int + 1 toBeKindOf: Integer.
```

And of course, we also expect the following to hold:

```{spec IntSpec.intAddSymmetric, int=allIntVals, arg={allIntVals, allDoubleVals}}
int + arg = (arg + int).
self expect: int + arg toBeKindOf: arg class.
```

##### Subtraction

Subtracting an arbitrary-precision integer from another returns an arbitrary-precision integer.

For example:

```{spec IntSpec.intSubtraction}
4 - 3 = 1.
-4 - 3 = -7.
```

Subtracting a `Double` from an integer results in a `Double` value.

For example:
```{spec IntSpec.doubleSubtraction}
self expect: 4 - 3.3 toEqual: 0.7 within: 0.00000001.
self expect: -4 - 3.5 toEqual: -7.5 within: 0.00000001.
```

Furthermore, the following should hold for `int` being any integer value:

```{spec IntSpec.intSubDecrease, int=allIntVals}
int - 1 < int.
self expect: int - 1 toBeKindOf: Integer.
```

And of course, we also expect the following to hold:

```{spec IntSpec.intSubAbsSymmetric, int=allIntVals, arg={allIntVals, allDoubleVals}}
(int - arg) abs = (arg - int) abs.
self expect: int - arg toBeKindOf: arg class.
```


[SOM]: http://www.hpi.uni-potsdam.de/hirschfeld/projects/som/
[SOM-st]: https://som-st.github.io