Skip to content

Commit

Permalink
add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
antonkesy committed Mar 16, 2024
1 parent e45dca9 commit 4db0ed2
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 18 deletions.
21 changes: 14 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ubuntu:22.04
FROM ubuntu:22.04 as base

ENV TZ=Europe
ENV DEBIAN_FRONTEND noninteractive
Expand All @@ -14,19 +14,26 @@ RUN stack --compiler ghc-9.4.7 setup
RUN apt-get -y install python3-pip
RUN pip install pre-commit

# formatter
RUN stack install ormolu
FROM base as build

WORKDIR /peter-lang

COPY . /peter-lang

# cancel the build if there are formatting errors
RUN ormolu --mode check $(find . -name '*.hs')

# build project
RUN stack build

FROM build as exe
ENTRYPOINT ["./peter.sh"]
CMD ["--help"]

FROM build as test

# formatter
RUN stack install ormolu

# cancel the build if there are formatting errors
# RUN ormolu --mode check $(find . -name '*.hs')

# run tests
RUN stack test

Expand Down
135 changes: 124 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,139 @@
# peter-lang

Useless and barely functional toy programming language written in Haskell
Useless and barely functional toy programming language interpreter written in Haskell from scratch (without any research how to actually lay things out)

The missing link between C and Python

<img src="https://m.media-amazon.com/images/M/MV5BMmQwNWY0MzMtZTgyNy00ZTM1LWI0ZDgtY2Q3NGQ4ZjhhN2U2XkEyXkFqcGdeQXVyODQyNDU4OTk@._V1_.jpg" width="720">

## Syntax

C style syntax with Python like runtime interpretation and built in functions.

### Main

Main function `void main() {}` is the entry point.

```
void main() {
int i = 1;
int k = i + 1;
print("Hello, World!");
}
```

## Syntax
Alternately, statements are executed from top to bottom in case no main is found.

```
print("Hello, World!");
```

### Primitives

- void
- bool
- int
- float
- str

### Conversion

- `str(1)` -> `"1"`
- `int("1")` -> `1`
- `float("1.3")` -> `1.3`

#### Operations

There is no operator precedence

| Operation | void | bool | int | float | str |
| :-------: | :--: | :--: | --- | ----- | --- |
| + | x | x ||||
| - | x | x ||| x |
| \* | x | x ||| x |
| \\ | x | x || x | x |
| % | x | x || x | x |
| == | x |||||
| != | x |||||
| < | x |||| x |
| > | x |||| x |
| <= | x |||| x |
| >= | x |||| x |
| && | x ||| x | x |
| \|\| | x ||| x | x |

### Flow Control

If:

```
if 1 < 2 {
i = 1;
} else {
i = -1;
}
```

C-Style
while:

```
int j = 0;
while j < 10 {
println(str(j));
j = j + 1;
}
```

### Functions

```
int f() {
return 42;
}
void main() {
print("Hello, World!");
int x = f();
}
```

### Structs

```
struct T {
int x;
int y;
}
T t;
t.x = 2;
```

## Limitations
### Built In

- print -> prints
- println -> prints line
- input -> reads stdin

## Limitations & Issues

- left side of operation has to be atomic (because of [left recursive grammar](https://en.wikipedia.org/wiki/Left_recursion))
- no deep copies of structs (yet)
- many bugs
- bad error messages from parser

## Installation

- left side of operation has to be atomic
### Native

Dependencies:

- [stack](https://docs.haskellstack.org/en/stable/)
- ghc-9.4.7: `stack --compiler ghc-9.4.7 setup`

### Docker

```bash
docker build --target exe -t peter .
docker run peter ./examples/print.mmm
```

## Usage

Expand All @@ -42,9 +154,10 @@ stack run -- ./examples/short_hello_world.mmm
stack run -- -i "print(\"Hello, World\");"
```

### Tests
## Tests

`stack test`
- `stack test`
- `cd ./test/E2E/Interpreter/examples/ && ./check_examples.sh`

## Formatting

Expand All @@ -56,4 +169,4 @@ ormolu --mode inplace $(find . -name '*.hs')

## CI

`docker build .`
`docker build .` + GitHub Actions
16 changes: 16 additions & 0 deletions examples/primitives.mmm
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
void v = ();
bool = true;
int i = 1;
float f = 2.0;
str s = "hello";

println(str(i));
println(str(f));

if 1 > int("0") {
println("bigger")
}

if 1 < int(3.2) {
println("smaller")
}
5 changes: 5 additions & 0 deletions peter.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

EXE="stack run --"

$EXE "$@"
1 change: 1 addition & 0 deletions src/Interpreter/BuiltIn.hs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ toInt =
valueToInt :: [Value] -> Int
valueToInt val = case val of
[IntValue i] -> i
[FloatValue f] -> truncate f
[StringValue s] -> read s
_ -> error ("No matching type for toInt: " ++ show val)

Expand Down
2 changes: 2 additions & 0 deletions src/Interpreter/Operation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ interpretOperation Gt (FloatValue left) (FloatValue right) = BoolValue $ left >
interpretOperation Le (FloatValue left) (FloatValue right) = BoolValue $ left <= right
interpretOperation Ge (FloatValue left) (FloatValue right) = BoolValue $ left >= right
interpretOperation Eq (FloatValue left) (FloatValue right) = BoolValue $ left == right
interpretOperation Neq (FloatValue left) (FloatValue right) = BoolValue $ left /= right
-- String
interpretOperation Plus (StringValue left) (StringValue right) = StringValue $ left ++ right
interpretOperation Eq (StringValue left) (StringValue right) = BoolValue $ left == right
-- Invalid
interpretOperation operator left right = error $ "Unsupported operation: " ++ show operator ++ " " ++ show left ++ " " ++ show right
2 changes: 2 additions & 0 deletions test/E2E/Interpreter/examples/check_examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ for item in "${file_paths[@]}"; do
IFS=':' read -r file expected_output <<< "$item"
check_stdout "$file" "$expected_output"
done

echo "All tests passed"

0 comments on commit 4db0ed2

Please sign in to comment.