Skip to content

Commit

Permalink
Added a lot of features. Release-candidate 1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
teodoran committed Aug 14, 2016
1 parent a210da0 commit 1e1c3bc
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 63 deletions.
81 changes: 74 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
stck
STCK
====
_a stack-based programming language_

stck is is a programming languague inspired by [Forth](https://en.wikipedia.org/wiki/Forth_(programming_language)). Variables are never declared, values is just placed on a global stack. Syntax is minimal. Currently, the only supported data-type is 32-bit integers.
STCK (pronounced stick) is is a programming languague inspired by [Forth](https://en.wikipedia.org/wiki/Forth_(programming_language)). Variables are never declared, values is just placed on a global stack. Syntax is minimal. The only supported data-type is 32-bit integers.


Installation
------------

You'll need a F# compiler (fsharpc/fshapri) to compile the stck interpreter. [This guide](http://fsharp.org/use/linux/) is usefull if you're using Linux. When the compiler is installed, simply run:
A very limited choice of prebuilt binaries can be found in the /binaries folder. If you can't find a binary that works for you, you'll need a F# compiler (fsharpc/fshapri) to compile the STCK interpreter. [This guide](http://fsharp.org/use/linux/) is usefull if you're using Linux. When the compiler is installed, navigate to the folder containing `stck.fs` and run:

fsharpc stck.fs && ./stck.exe ./euler-one.stck
fsharpc stck.fs && ./stck.exe ./samples/euler-one.stck

This should compile the interpreter into stck.exe, and run a stck-program, solving the first [Project Euler](https://projecteuler.net/) problem. Just running stck.exe will launch the interactive interpreter.


Using the languague
-------------------

**Delimiting lines**

When using the interpreter, return acts as the line delimiter.
Expand Down Expand Up @@ -55,17 +58,66 @@ Lines cannot be nested.
dup
[2; 2]

`over` see the [Forth dokumentation](http://wiki.laptop.org/go/Forth_stack_operators)
`2dup` will duplicate the two topmost elements on the stack.

2 3
[3; 2]
2dup
[3; 2; 3; 2]

`over` will copy the second element on the stack.

2 3
[3; 2]
over
[2; 3; 2]

`rot` will move the third element to the top of the stack.

1 2 3
[3; 2; 1]
rot
[1; 3; 2]

`rot` see the [Forth dokumentation](http://wiki.laptop.org/go/Forth_stack_operators)
`len` will return the size of the stack and push the size onto the stack.

1 1
[1; 1]
len
[2; 1; 1]

`empty` will check if the stack is empty, and push the result onto the stack.

[]
empty
[1]

`max` and `min` will remove all elements on the stack, leaving only the largest or smallest integer.

1 3 1 max
[3]
1 -2 1 min
[-2]

In addition, the [Forth dokumentation](http://wiki.laptop.org/go/Forth_stack_operators) has a good description of different stack operators, along with reference implementations for less basic operators.

**Math**

The following operators are supported: `+` (addition), `-` (substraction), `*` (multiplication), `/` (division) and `%` (modulo). All operators perform on the two upmost elements on the stack, and push the result back on the stack. Beware of integer division as it will floor the result.
The following operators are supported: `+` (addition), `-` (substraction), `*` (multiplication), `/` (division) `i/` (integer division) and `%` (modulo). All operators, except `/` perform on the two upmost elements on the stack, and push the result back on the stack as one number.

5 2 -
[3]

`/` divides two integers, and push the result of the division onto the stack as two numbers (integer quotient and remainder). The remainder is always given as a number with six digits. In the case where the remainder exceeds six digits, no rounding is performed.

2 3 /
[666666; 0]

In addition, the remainder can be computed directly with the `rem` operator.

2 3 rem
[666666]

**Boolean operators**

False is represented by `0`(zero) and anything else is considered true. The following boolean operators are supported: `=` (equal), `>` (greater than), `<` (less than), and `not`. All operators perform on the two upmost elements on the stack, and push the result back on the stack.
Expand Down Expand Up @@ -111,3 +163,18 @@ The contents of a subroutine is contained within a line. So remeber to terminate

`hprint` prints the content of the heap. This will list all declared subroutines.
`sprint` prints the content of the stack. This is equal to the reply given by the interpreter.
`quit` exits the interprenter.


Releaselog
----------

**V 1.1**

Changed behaviour of /. Integer division is now performed with i/ and / performs regular division.

Added the command `quit`, `2dup`, `len`, `max`, `min` and `remainder`.

**V 1.0**

Initial release.
38 changes: 0 additions & 38 deletions euler-one.stck

This file was deleted.

38 changes: 38 additions & 0 deletions samples/euler-one.stck
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Project Euler problem one !
// Ported from http://blog.kjempekjekt.com/2011/12/18/forth/ !

# next-is-zero
dup 0 =
!

# multiple-of-3
dup 3 % 0 =
!

# multiple-of-5
dup 5 % 0 =
!

# keep-number-if-multiple-of-3-or-5
multiple-of-3 ?
dup
: multiple-of-5 ?
dup
: ; ;
1 -
!

# generate-numbers
next-is-zero not ?
keep-number-if-multiple-of-3-or-5 generate-numbers
: . ;
!

# sum-numbers
+
len 1 = not ?
sum-numbers
: ;
!

999 generate-numbers sum-numbers !
45 changes: 45 additions & 0 deletions samples/euler-three.stck
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Project Euler problem three !
// The prime factors of 13195 are 5, 7, 13 and 29. !
// What is the largest prime factor of the number 600851475143 ? !

// The implementation below is brute-force based, and will not teminate within reasonable time, given 600851475143 as input. !
// Even calculating the prime factors of 13195 will take several minutes. !
// Although not practical, this example is left as another sample of STCK-code !


# divides-13195
dup 13195 swap % 0 =
!

# is-larger-than-13195
dup 13195 <
!

# is-even
dup 2 % 0 =
!

# is-prime
dup 2 = ?
0
: dup dup is-prime-rec ;
!

# is-prime-rec
1 -
dup 1 = ?
. . 1
: 2dup rem 0 = ?
. . 0
: is-prime-rec ; ;
!

# gen-prime
1 +
is-larger-than-13195 not ? is-prime ? divides-13195 ?
dup : ; : ;
gen-prime
: . ;
!

1 gen-prime max !
19 changes: 10 additions & 9 deletions euler-two.stck → samples/euler-two.stck
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Project Euler problem two !
// Considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms. !

# 2dup over over !

# next-fib 2dup + !
# next-fib
2dup +
!

# is-even
dup 2 % 0 =
Expand All @@ -15,16 +15,17 @@

# fib-under-4m
next-fib
dup 4000000 >
? fib-under-4m
dup 4000000 > ?
fib-under-4m
: . ;
!

# sum-if-even
swap is-even
? + : . ;
swap next-is-zero
? .
swap is-even ?
+
: . ;
swap next-is-zero ?
.
: swap sum-if-even ;
!

Expand Down
33 changes: 24 additions & 9 deletions stck.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ open System
open System.IO
open System.Text.RegularExpressions

let standard_library = [
("2dup", ["over"; "over"]);
("rem", ["dup"; "rot"; "swap"; "2dup"; "i/"; "*"; "-"; "1000000"; "*"; "swap"; "i/"]);
("/", ["2dup"; "i/"; "rot"; "rot"; "rem"]);
("empty", ["len"; "0"; "="]);
("max", ["len"; "1"; "="; "not"; "?"; "2dup"; ">"; "?"; "swap"; "."; ":"; "."; ";"; "max"; ":"; ";"]);
("min", ["len"; "1"; "="; "not"; "?"; "2dup"; "<"; "?"; "swap"; "."; ":"; "."; ";"; "min"; ":"; ";"])
]

let push e stack =
e :: stack

Expand All @@ -28,7 +37,7 @@ let dup stack =

let over stack =
match stack with
| a :: b :: rest -> (b :: a :: b :: rest)
| a :: b :: rest -> b :: a :: b :: rest
| _ ->
printfn "Cannot over on the stack"
stack
Expand All @@ -39,6 +48,8 @@ let rot stack =
| _ ->
printfn "Cannot rot on the stack"
stack
let len (stack:List<int>) =
push stack.Length stack

let isInt string =
let couldParse, value = Int32.TryParse(string)
Expand Down Expand Up @@ -103,16 +114,18 @@ let exec exp stack =
| "dup" -> dup stack
| "over" -> over stack
| "rot" -> rot stack
| "len" -> len stack
| "+" -> add stack
| "-" -> substract stack
| "*" -> multiply stack
| "/" -> divide stack
| "i/" -> divide stack
| "%" -> modulo stack
| "=" -> equal stack
| ">" -> greater stack
| "<" -> less stack
| "not" -> not stack
| "sprint" -> sprint stack
| "quit" -> exit 0
| _ ->
if isInt exp then
push (Int32.Parse(exp)) stack
Expand Down Expand Up @@ -180,7 +193,6 @@ let rec eval exps hs =
| [] -> eval tail (heap, exec head stack)
| def -> eval (def @ tail) hs


let rec loop hs =
let exps = tokens (Console.ReadLine())

Expand All @@ -204,19 +216,22 @@ let lines (s:string) =

let rec run file =
let statements = lines (File.ReadAllText(file))
System.String.Join(" ", evaluate statements ([], []))
System.String.Join(" ", evaluate statements (standard_library, []))

let load file =
match File.Exists(file) with
| false -> printfn "The file %s does not exist" file
| true -> printfn "%s" (run file)

[<EntryPoint>]
let main args =
match Array.length args > 0 with
| true ->
match File.Exists(args.[0]) with
| false -> printfn "The file %s does not exist" args.[0]
| true -> printfn "%s" (run args.[0])
load args.[0]
| false ->
printfn ""
printfn "Welcome to STCK 1.0, a stack-based programming language"
printfn "Welcome to STCK 1.1, a stack-based programming language"
printfn ""
loop ([], [])
loop (standard_library, [])

0
6 changes: 6 additions & 0 deletions sublime-package/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
STCK build and syntax definition for Sublime Text 3
===================================================

This folder contains STCK configuration for the Sublime Text 3 editor.

Install the package by copying the /STCK folder into your sublime-packages folder. Select the menu option Preferences -> Browse Packages... if you're unshure where your sublime-packages folder is located.
8 changes: 8 additions & 0 deletions sublime-package/STCK/STCK.sublime-build
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"cmd": ["stck.exe", "$file"],
"osx": {
"cmd": ["stck", "$file"]
},
"file_regex": "^((.*)\\.(stck(i|x)?))\\(([0-9]*),([0-9]*)\\):.*$",
"selector": "source.fsharp"
}
Loading

0 comments on commit 1e1c3bc

Please sign in to comment.