Website

Check-in [086f0ffde5]
Login
Overview
Comment:Update playground to work with new syntac, and remove any reference to words and quotations and instead use functions.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 086f0ffde5048a55e9655669d8d4606843637129f85229d2ff265e66861a07bf
User & Date: robin.hansen on 2021-06-10 10:09:35
Other Links: manifest | tags
Context
2021-06-11
14:42
Final touches for v0.2.0-alpha release. check-in: 49964070d8 user: robin.hansen tags: trunk
2021-06-10
10:09
Update playground to work with new syntac, and remove any reference to words and quotations and inst... check-in: 086f0ffde5 user: robin.hansen tags: trunk
09:54
Update dependencies and Stabel compiler. check-in: 587f92f528 user: robin.hansen tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Lesson01.elm from [92c3cb2380] to [141d519185].

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
import LessonContract exposing (LessonContract)
import String.Extra as String


contract : LessonContract
contract =
    { key = "L01"
    , label = "Word definition"
    , content = String.trim <| String.unindent content
    }


content : String
content =
    """
    # Welcome to the playground
    # Here you can learn the Stabel language by reading and toying around with examples.
    # You can find more examples in the dropdown above.

    # A '#' character marks the beginning of a line comment.
    # Comments are ignored by the compiler, and serves the purpose of making things clearer for a human.
    
    # Below you'll find a simple word definition.
    # In other programming languages, this will usually be called a function definition.

    def: main   # 1
    entry: true # 2
    : 5         # 3


    # 1. We begin a new word definition, and this word will be called main.
    # 2. 'main' is an entry point, this is called when your program starts up.

    # 3. A single ':' without any prefix marks the definition of the word. In this word, we're simply returning the number 5 (the last element in a definition is its return value).

    # Hit the 'run' button above to execute this Stabel program.
    """







|







|






|
<

|
<
|


<
<
>
|



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
import LessonContract exposing (LessonContract)
import String.Extra as String


contract : LessonContract
contract =
    { key = "L01"
    , label = "Function definition"
    , content = String.trim <| String.unindent content
    }


content : String
content =
    """
    # Welcome to the playground!
    # Here you can learn the Stabel language by reading and toying around with examples.
    # You can find more examples in the dropdown above.

    # A '#' character marks the beginning of a line comment.
    # Comments are ignored by the compiler, and serves the purpose of making things clearer for a human.
    
    # Below you'll find a simple function definition.


    def: main # 1

    : 5       # 2




    # 1. We begin a new function definition, and this word will be called main. The name 'main' is important, when you click the 'run' button the playground will try to execute the 'main' function.
    # 2. A single ':' without any prefix marks the definition of the function implementation. In this function, we're simply returning the number 5 (the last element in a definition is its return value).

    # Hit the 'run' button above to execute this Stabel program.
    """

Modified src/Lesson02.elm from [0441412e0f] to [c7d3058766].

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
    , content = String.trim <| String.unindent content
    }


content : String
content =
    """
    # In the last example we saw that the last element in a word definition, was returned.
    # In fact, words can have multiple return values:

    def: four-and-five
    : 4 5

    # How does this work?
    # The first thing to understand is that Stabel is stack oriented. 
    # What really happens in the word definition above is that, when executed, the numbers 4 and 5 will be put on a stack.

    # What happens when a word is placed on the stack? It executes!

    def: main
    entry: true
    : four-and-five +

    # Executing 'main' will first execute the word 'four-and-five'
    # 'four-and-five' will place the numbers 4 and 5 on the stack. 
    # Then the word '+' will execute, which pops two numbers off the stack, adds them together, and places the sum on the stack.

    # Whatever is on the stack at the end of a program, is printed in the black box to the right.

    # There aren't really any return values. Every word simply accepts, modifies and returns a stack.
    """







|
|






|

|


<


|

|



|

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
    , content = String.trim <| String.unindent content
    }


content : String
content =
    """
    # In the last example we saw that the last element in a function definition, was returned.
    # Functions can have multiple return values.

    def: four-and-five
    : 4 5

    # How does this work?
    # The first thing to understand is that Stabel is stack oriented. 
    # What really happens in the function above is that, when executed, the numbers 4 and 5 will be put on the stack.

    # What happens when a function is placed on the stack? It executes!

    def: main

    : four-and-five +

    # Executing 'main' will first execute the function 'four-and-five'
    # 'four-and-five' will place the numbers 4 and 5 on the stack. 
    # Then the function '+' will execute, which pops two numbers off the stack, adds them together, and places the sum back on the stack.

    # Whatever is on the stack at the end of a program, is printed in the black box to the right.

    # There aren't really any return values. Every function simply accepts, modifies and returns a stack.
    """

Modified src/Lesson03.elm from [ea712cc430] to [3cbd879e81].

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
29
30
31
32
33
34
35
36
37
38
39
40
    }


content : String
content =
    """
    # Sometimes it can be nice to re-arrange values on the stack. 
    # Stabel has some built in words for that purpose.

    # 'dup' let's you duplicate a value

    def: square
    : dup *

    # 'swap' switches the positions of two values
................................................................................

    def: drop-first
    : swap drop

    # There are more, but the ones listed above are the most common

    def: main
    entry: true
    : 4 5
      drop-first
      square
    """







|







 







<




12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
29
30
31
32
33
34
35

36
37
38
39
    }


content : String
content =
    """
    # Sometimes it can be nice to re-arrange values on the stack. 
    # Stabel has some built in functions for that purpose.

    # 'dup' let's you duplicate a value

    def: square
    : dup *

    # 'swap' switches the positions of two values
................................................................................

    def: drop-first
    : swap drop

    # There are more, but the ones listed above are the most common

    def: main

    : 4 5
      drop-first
      square
    """

Modified src/Lesson04.elm from [37cbbfd48f] to [327927e4c5].

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


content : String
content =
    """
    # Stabel is statically typed. 
    # In most cases, Stabel is smart enough to infer the types.
    # The word definitions in the previous example are shown here with type annotations.

    def: square
    type: Int -- Int
    : dup *

    def: drop-first
    type: Int Int -- Int
    : swap drop

    def: main
    type: -- Int
    entry: true
    : 4 5
      drop-first
      square

    # '--' is what separates requirements from results.
    # 'drop-first' requires two Ints to be on the stack, and will replace them with one Int.
    # 'main' requires nothing to be on the stack, and will add one Int to it.
    """







|











<








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


content : String
content =
    """
    # Stabel is statically typed. 
    # In most cases, Stabel is smart enough to infer the types.
    # The function definitions in the previous example are repeated here with type annotations.

    def: square
    type: Int -- Int
    : dup *

    def: drop-first
    type: Int Int -- Int
    : swap drop

    def: main
    type: -- Int

    : 4 5
      drop-first
      square

    # '--' is what separates requirements from results.
    # 'drop-first' requires two Ints to be on the stack, and will replace them with one Int.
    # 'main' requires nothing to be on the stack, and will add one Int to it.
    """

Modified src/Lesson05.elm from [ef2b7c97d5] to [3cba359f98].

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


content : String
content =
    """
    # Stabel allows you to define compound structures.

    deftype: Coordinate
    : x Int
    : y Int

    # This will define a 'Coordinate' which has two members, x and y, which are integers.

    # Stabel will also generate some words for you to be able to read and modify this structure.
    # '>Coordinate' is a word that requires two Ints to be on the stack, and will create a Coordinate with those numbers as x and y, respectively.
    # '>x' and '>y' requires an Int and a Coordinate to be on the stack, and sets the x/y member to the provided Int.
    # 'x>' and 'y>' will return the x/y value of a Coordinate, which must be on the stack.

    # The '>' character can be read as 'into'. 
    # '>x' is then read as 'into x' and 'x>' is read as 'x into'. 
    # Either you're reading from the stack and into x, or from x into the stack.

    # Do note that '>' and '<' is not special syntax, but can be used in the name of any word.

    def: main
    type: -- Int
    entry: true
    : 1 2 >Coordinate # creates a Coordinate(x=1, y=2)
      5 >x            # Replaces the Coordinate(x=1, y=2) with Coordinate(x=5, y=2)
      x>              # Replaces the Coordinate(x=5, y=2) with the value of x.
    """







|





|
|







|



<




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


content : String
content =
    """
    # Stabel allows you to define compound structures.

    defstruct: Coordinate
    : x Int
    : y Int

    # This will define a 'Coordinate' which has two members, x and y, which are integers.

    # Stabel will also generate some functions for you to be able to read and modify this structure.
    # '>Coordinate' is a function that requires two Ints to be on the stack, and will create a Coordinate with those numbers as x and y, respectively.
    # '>x' and '>y' requires an Int and a Coordinate to be on the stack, and sets the x/y member to the provided Int.
    # 'x>' and 'y>' will return the x/y value of a Coordinate, which must be on the stack.

    # The '>' character can be read as 'into'. 
    # '>x' is then read as 'into x' and 'x>' is read as 'x into'. 
    # Either you're reading from the stack and into x, or from x into the stack.

    # Do note that '>' and '<' is not special syntax, but can be used in the name of any function.

    def: main
    type: -- Int

    : 1 2 >Coordinate # creates a Coordinate(x=1, y=2)
      5 >x            # Replaces the Coordinate(x=1, y=2) with Coordinate(x=5, y=2)
      x>              # Replaces the Coordinate(x=5, y=2) with the value of x.
    """

Modified src/Lesson06.elm from [5638076762] to [0d08556446].

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
import LessonContract exposing (LessonContract)
import String.Extra as String


contract : LessonContract
contract =
    { key = "L06"
    , label = "Quotations"
    , content = String.trim <| String.unindent content
    }


content : String
content =
    """
    # Stabel allows you to place word references on the stack, and even construct anonymous words.
    # We call them quotations. Other languages call them anonymous functions.

    # For this example, let's bring back the Coordinate type from the previous example.

    deftype: Coordinate
    : x Int
    : y Int

    # Now, imagine we want to create a word that allows you to modify the 'x' member in any way imaginable.
    # This is a good use case for quotations.

    def: update-x
    type: Coordinate [ Int -- Int ] -- Coordinate
    : swap    # bring Coordinate to the top of the stack
      dup x>  # read value of x without loosing the original Coordinate
      -rotate # rotates the three top stack elements one space to the left
      !       # execute qutotation
      >x      # set x to whatever was returned by quotation

    def: main
    entry: true
    : 1 2 >Coordinate
      [ 1 + ] update-x
      x>

    # Quotations are wrapped in brackets. Think of them as inline word definitions.

    """







|







|
<



|



|
|










<




|
>

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
import LessonContract exposing (LessonContract)
import String.Extra as String


contract : LessonContract
contract =
    { key = "L06"
    , label = "Anonymous functions"
    , content = String.trim <| String.unindent content
    }


content : String
content =
    """
    # Stabel allows you to place function references on the stack, and even construct anonymous functions.


    # For this example, let's bring back the Coordinate type from the previous example.

    defstruct: Coordinate
    : x Int
    : y Int

    # Now, imagine we want to create a function that allows you to modify the 'x' member in any way imaginable.
    # This is a good use case for anonymous functions.

    def: update-x
    type: Coordinate [ Int -- Int ] -- Coordinate
    : swap    # bring Coordinate to the top of the stack
      dup x>  # read value of x without loosing the original Coordinate
      -rotate # rotates the three top stack elements one space to the left
      !       # execute qutotation
      >x      # set x to whatever was returned by quotation

    def: main

    : 1 2 >Coordinate
      [ 1 + ] update-x
      x>

    # Anonymous functions are wrapped in brackets. 
    # Think of them as inline function definitions.
    """

Modified src/Lesson07.elm from [6c07cb562b] to [3cdcf059ea].

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
import LessonContract exposing (LessonContract)
import String.Extra as String


contract : LessonContract
contract =
    { key = "L07"
    , label = "Unions and multiwords"
    , content = String.trim <| String.unindent content
    }


content : String
content =
    """
    # Stabel supports the concept of a Union type

    defunion: State
    : On
    : Off

    deftype: On
    deftype: Off

    # This defines a Union of On and Off, called State.
    # Whenever you use State as a type, you're saying that it really could be either On or Off.
    # To handle such types we need to use multi-words.
    # Multi-words are words with a definition that depends on the type that is actually present on the stack.

    defmulti: state->int
    type: State -- Int
    when: On
      drop 1
    when: Off
      drop 0

    def: main
    entry: true
    : >On state->int


    """







|







|





|
|

|

|
|



|

|



<
|
>
>

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
import LessonContract exposing (LessonContract)
import String.Extra as String


contract : LessonContract
contract =
    { key = "L07"
    , label = "Unions and multifunctions"
    , content = String.trim <| String.unindent content
    }


content : String
content =
    """
    # Stabel supports the concept of a union type

    defunion: State
    : On
    : Off

    defstruct: On
    defstruct: Off

    # This defines a union of On and Off, called State.
    # Whenever you use State as a type, you're saying that it really could be either On or Off.
    # To handle such types we need to use multi-functions.
    # Multi-functions are functions with a definition that depends on the type that is present on the stack.

    defmulti: state->int
    type: State -- Int
    : On
      drop 1
    : Off
      drop 0

    def: main

    : On state->int

    # Notice that when a struct is defined without any members, like On and Off, that the constructor is just the name of the type without the > prefix.
    """

Modified src/Lesson08.elm from [418a8dc6b7] to [45038982b1].

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
    , content = String.trim <| String.unindent content
    }


content : String
content =
    """
    # Multi-words allows you to be very specific about when a specific condition applies.

    deftype: Coordinate
    : x Int
    : y Int

    defmulti: origo?
    type: Coordinate -- Int
    when: Coordinate( x 0 y 0 )
      drop 1
    when: Coordinate
      drop 0

    def: main
    entry: true
    : 1 1 >Coordinate
      origo?
    """







|

|





|

|



<



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32
33
34
    , content = String.trim <| String.unindent content
    }


content : String
content =
    """
    # Multi-functions allows you to be very specific about when a specific condition applies.

    defstruct: Coordinate
    : x Int
    : y Int

    defmulti: origo?
    type: Coordinate -- Int
    : Coordinate( x 0 y 0 )
      drop 1
    : Coordinate
      drop 0

    def: main

    : 1 1 >Coordinate
      origo?
    """

Modified src/Lesson09.elm from [25dc9187ff] to [36d02866ed].

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
    # Unions allow for some interesting API designs.
    # Let's implement a List data structure.

    defunion: List a
    : NonEmptyList a
    : EmptyList

    deftype: NonEmptyList a
    : first a
    : rest (List a)

    deftype: EmptyList

    # Notice retrieving the first element of a list can only be done if you have a NonEmptyList.
    # Also notice that a lowercased type acts as a placeholder for any type, a generic type.

    def: push
    type: (List a) a -- (NonEmptyList a)
    : swap >NonEmptyList

    defmulti: first-or-default
    type: (List a) a -- a
    when: NonEmptyList
      drop first>
    when: EmptyList
      swap drop

    # Here we can specify that the result of adding an element to a List, always result in a NonEmptyList.
    # A NonEmptyList is still a List, though.

    def: main
    entry: true
    : >EmptyList
      10 push
      0 first-or-default # Could have used 'first>' here.
    """







|



|

|








|

|






<
|



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
    # Unions allow for some interesting API designs.
    # Let's implement a List data structure.

    defunion: List a
    : NonEmptyList a
    : EmptyList

    defstruct: NonEmptyList a
    : first a
    : rest (List a)

    defstruct: EmptyList

    # Notice that retrieving the first element of a list can only be done if you have a NonEmptyList.
    # Also notice that a lowercased type acts as a placeholder for any type, a generic type.

    def: push
    type: (List a) a -- (NonEmptyList a)
    : swap >NonEmptyList

    defmulti: first-or-default
    type: (List a) a -- a
    : NonEmptyList
      drop first>
    : EmptyList
      swap drop

    # Here we can specify that the result of adding an element to a List, always result in a NonEmptyList.
    # A NonEmptyList is still a List, though.

    def: main

    : EmptyList
      10 push
      0 first-or-default # Could have used 'first>' here.
    """