Skip to content

Commit

Permalink
Merge pull request #8 from fabaindaiz/dev
Browse files Browse the repository at this point in the history
Dev: Analyse & readme
  • Loading branch information
fabaindaiz authored Aug 15, 2023
2 parents 68eb442 + 89a7394 commit d879735
Show file tree
Hide file tree
Showing 34 changed files with 867 additions and 466 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,8 @@ _opam/
*.s
*.run

# VSCode configs
.vscode/

# Segmentation fault
core
5 changes: 0 additions & 5 deletions .vscode/settings.json

This file was deleted.

122 changes: 122 additions & 0 deletions LANGUAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# RED language

RED language is a programming language designed to write redcode programs. The language is designed to be easy to learn and use, and to be compiled to redcode programs. The following is a description of the language and its features.

### Language features

- Provide a simple syntax to write redcode programs with control flows
- Eliminate the need to write instruction modifiers and addressing modes

### Language syntax

The language syntax is based on s-expressions. The syntax is designed to be easy to read and write, and to be easy to parse and compile. The following is a description of the language components and their syntax.

### Notices

- The project is in development and RED language is not the final version. Important changes can be made until first release.


## Arguments (arg)

Arguments are used in instructions and conditions to specify the operands.
If you want to store some value, you need to use a argument.

An argument have a addressing mode and a value.

- (none) replaced by immediate 0
- (var) declare a argument using default mode
- (mode var) declare a argument using specified mode

### Variables (var)

Variables are numbers or strings used to store values.
By default, numbers use immediate mode and strings use direct mode.

- (number) integer signed or unsigned number
- (string) string reference to let variable or label

If the string corresponds to some variable in scope, the string will be replaced by a reference to this variable, otherwise the string will be kept referencing a label

### Addresing modes (mode)

Addresing modes are used to specify how the argument is used in the instruction. If the addressing mode is not specified, the default mode is used.

- (Imm var) | (# var) immediate addresing to var
- (Dir var) | ($ var) direct addresing to var
- (Ind var) | (@ var) indirect addresing to var
- (Dec var) | (< var) decrement var and indirect addresing to var
- (Inc var) | (> var) indirect addresing to var and increment var
- (instr var) | (% var) points to the instruction instead of the value
- (store var) | (! var) store var value in this place (field is automatic)


## Conditions (cond)

Conditions are used in a control flow intruction to specify when the control flow is executed. There are two types of conditions: unary and binary, each one with different extra instructions added to the code to work.

### Unary conditions (cond1)

Unary conditions are used to specify when the control flow is executed based on one argument. Generate an extra instruction in the code.

- (JZ x) x is zero
- (JN x) x is not zero
- (DZ x) decrement x and x is zero
- (DN x) decrement x and x is not zero

### Binary conditions (cond2)

Binary conditions are used to specify when the control flow is executed based on two arguments. Generate two extra instructions in the code.

- (EQ x y) x and y equals
- (NE x y) x and y not equals
- (GT x y) x is greater than y
- (LT x y) x is less than y


## Instructions

Instructions are used to specify the operation to be performed. Instruction modifiers are automatically generated during compilation.

### redcode instructions

All redcode instructions are available for direct use.
Square brackets '[]' indicates that the argument is optional.

- (NOP [arg1] [arg2]) no operation (arg1 & arg2 only store data)

- (DAT arg1 arg2) data values
- (MOV arg1 arg2) move arg1 to arg2

- (ADD arg1 arg2) add arg1 to arg2
- (SUB arg1 arg2) sub arg1 from arg2
- (MUL arg1 arg2) mul arg1 to arg2
- (DIV arg1 arg2) div arg1 from arg2
- (MOD arg1 arg2) mod arg1 from arg2

- (JMP arg1 [arg2]) jump to arg1 (arg2 only store data)
- (SPL arg1 [arg2]) split to arg1 (arg2 only store data)

- (JMZ arg1 arg2) jump to arg1 if arg2 is zero
- (JMN arg1 arg2) jump to arg1 if arg2 is not zero
- (DJN arg1 arg2) decrement arg2 and jump to arg1 if arg2 is not zero

- (SEQ arg1 arg2) skip next instruction if arg1 equals arg2
- (SNE arg1 arg2) skip next instruction if arg1 not equals arg2
- (SLT arg1 arg2) skip next instruction if arg1 is less than arg2

### Control flows

Control flows are used to specify the execution order of the instructions. Use control flows generates extra instructions in the code.

- (repeat body) repeat body forever (one extra instruction)
- (while cond body) repeat body while cond is true (one extra instruction + cond)
- (if cond body) execute body if cond is true (no extra instruction + cond)
- (do-while cond body) repeat body while cond is true (no extra instruction + cond)


### Other instructions

- (let (id arg) body) introduce a new variable in the scope (no extra instruction)

- (seq instrs) execure a sequence of instructions (one extra instruction)
- (label text) create a label in the code (no extra instruction)
16 changes: 2 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ src = # nothing by default
init:
dune build @check

test:
tests:
dune exec execs/run_test.exe -- test '$(F)'

ctest:
Expand All @@ -26,18 +26,6 @@ ctest:
compile:
dune exec execs/run_compile.exe $(src)

compile-run: $(subst .src,.run,$(src))
./$<

interp:
dune exec execs/run_interp.exe $(src)

%.run: %.o rt/sys.c
clang -o $@ $(CFLAGS) rt/sys.c $<

%.o: %.s
nasm -f $(BIN_FORMAT) -o $@ $<

%.s: %.src
dune exec execs/run_compile.exe $< > $@

Expand All @@ -47,5 +35,5 @@ interp:
clean: clean-test
rm -Rf _build

clean-test:
clean-tests:
find bbctests/ -type f -regex '.*\.\(o\|s\|run\|result\)' -delete
38 changes: 31 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,61 @@
# corewars-compiler
This software aims to be an easier way to write and optimize code for corewars. corewars-compiler uses its own mini functional language which can then be compiled into optimized redcode.
#### By fabaindaiz

work in progress
This software aims to be an easier way to write and optimize code for corewars. corewars-compiler uses its own mini functional language called RED which can then be compiled into optimized redcode.

### Requirements
- [BBCStepTester](https://github.com/fabaindaiz/BBCStepTester)
work in progress.

### Intepreters

### Instructions of use
- See REFERENCE.md for develop and run.
- See LANGUAGE.md for RED language reference.
- See TUTORIAL.md for a RED language tutorial.

#### Intepreters

To execute the resulting redcode you can use one of these redcode interpreters.

- [pMARS](https://corewar.co.uk/pmars.htm)
- [A.R.E.S.](https://corewar.co.uk/ares.htm)
- [PyMARS](https://github.com/rodrigosetti/corewar)
- [python MARS](https://github.com/rodrigosetti/corewar)

#### TODO

- Create a RED language tutorial
- Test all instructions modifiers and addressing modes
- Improve control flow instructions and conditions

## Acknowledgements

- Pleiad for [BBCTester](https://github.com/pleiad/BBCTester)


## References

#### Getting started

- [basic manual (spanish)](https://fdist.ucm.es/corewar/CoreWar.pdf)
- [the beginners' guide](https://vyznev.net/corewar/guide.html)
- [my first corewars book](https://www.corewars.org/docs/book1.html)

#### Redcode learning

- [corewars warrior hints](https://es.scribd.com/document/231018699/Core-War-Hints)
- [corewars tips & tricks](https://www.corewars.org/docs/tips.html)

#### Redcode wariors

- [redcode warriors](https://github.com/n1LS/redcode-warriors)
- [warriors sorted by type](http://moscova.inria.fr/~doligez/corewar/by-types/idx.htm)
- [warriors sorted by name](http://moscova.inria.fr/~doligez/corewar/by-name/complete.htm)

#### Redcode reference

- [1994 Core War Standard](https://corewar.co.uk/standards/icws94.txt)
- [REDCODE REFERENCE](https://corewa.rs/reference/pmars-redcode-94.txt)
- [ICWS94 validate](http://www.koth.org/planar/post/Validate1.1R.txt)

#### Coreward koth
#### Corewars koth

- [KotH](http://www.koth.org/koth.html)
- [hills](https://corewar.co.uk/hills.htm)
72 changes: 56 additions & 16 deletions REFERENCE.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,60 @@
# Reference Code for Deliverable 1
# Requirements & Setup

Starter code for compilers homework, [deliverable 1](https://users.dcc.uchile.cl/~etanter/CC5116/hw_1_enunciado.html)
To develop and run the compiler, you will need to use the following:

## Requirements & Setup
- [OCaml](https://ocaml.org/), version 4.12 (or newer), a programming language well-suited for implementing compilers (see below for the specific installation instructions).
- [Opam](https://opam.ocaml.org/doc/Install.html), version 2.0 (or newer), a package manager for ocaml libraries and tools.

See the [detailed description](https://users.dcc.uchile.cl/~etanter/CC5116-2020/#(part._materials)) on the page of the course.
In order to setup your ocaml environment, you should first [install opam](https://opam.ocaml.org/doc/Install.html), following the instructions for your distribution. Then create a switch with the right ocaml version and install the tools and libraries used in the course with the following invocations from the command line.

```bash
opam init
opam update
opam switch create compilation 5.0.0

# adapt according to your shell -- this is shown for bash
eval `opam env`
opam install dune utop merlin containers alcotest
```

A brief description of the installed tools and libraries:

- [dune](https://dune.build/), version 2.9 (or newer), a build manager for ocaml.
- [utop](https://github.com/ocaml-community/utop), a rich REPL (Run-Eval-Print-Loop) for ocaml with autocompletion and syntax coloring.
- [merlin](https://github.com/ocaml/merlin), provides contextual information on ocaml code to various IDEs.
- [containers](http://c-cube.github.io/ocaml-containers/), an extension to the standard library.
- [alcotest](https://github.com/mirage/alcotest), a simple and colourful unit test framework.

There is no specific IDE for OCaml. A time-tested solution is to use Emacs (with tuareg and merlin). I’m using the [OCaml Platform for VS Code](https://github.com/ocamllabs/vscode-ocaml-platform), which works pretty well and is under active development. There’s also some community-backed support for [IntelliJ](https://plugins.jetbrains.com/plugin/9440-reasonml), although I haven’t tried it.

For VS Code, you first need to install [OCaml LSP](https://github.com/ocaml/ocaml-lsp):

```bash
opam install ocaml-lsp-server
```

Then simply go to VS Code, lookup for the extension named VSCode OCaml Platform, and you should be good to go.

Hint for VS Code: run this in the VS Code integrated terminal for automatic rebuild when a file changes:

```bash
dune build --watch --terminal-persistence=clear-on-rebuild
```

We recommend using Linux or macOS, if possible. If you use Windows, then install the [Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/install). Past experience from students with WSL indicates that:

- When installing opam with add-apt-repository, it’s also necessary to apt install gcc, binutils-dev, make and pkg-config, and

- Call opam init with the switch --disable-sandboxing, as [explained here](https://stackoverflow.com/questions/54987110/installing-ocaml-on-windows-10-using-wsl-ubuntu-problems-with-bwrap-bubblewr).

## Organization of the repository

The organization of the repository is as follows:

- `dev/`: main OCaml files for the project submodules (ast, parser, interpreter, asm instructions, compiler)
- `execs/`: OCaml files for top-level executables (interpreter, compiler, tester)
- `src/`: main OCaml files for the project submodules (ast, parser, red instructions, compiler)
- `execs/`: OCaml files for top-level executables (compiler, tester)
- `bbctests/`: folder for black-box compiler tests (uses the BBCTester library, see below)
- `examples/`: folder for example source code files you may wish to interpret or compile directly
- `rt/sys.c`: the runtime system implemented in C

Additionally, the root directory contains configuration files for the dune package manager (`dune-workspace`, `dune-project`), and each OCaml subdirectory also contains `dune` files in order to setup the project structure.

Expand All @@ -30,7 +70,7 @@ The root directory contains a `Makefile` that provides shortcuts to build and te

- `make clean-tests`: cleans the tests output in the `bbctests` directory

- `make test`: execute the tests for the compiler defined in `execs/test.ml` (see below).
- `make tests`: execute the tests for the compiler defined in `execs/test.ml` (see below).
Variants include:
* `make ctest` for compact representation of the tests execution
* you can also add `F=<pat>` where `<pat>` is a pattern to filter which tests should be executed (eg. `make test F=arith` to run only test files whose name contains `arith`)
Expand All @@ -39,18 +79,14 @@ The root directory contains a `Makefile` that provides shortcuts to build and te
- you can build the executables manually with `make <executable_name>.exe`. For instance, `make run_compile.exe` builds the compiler executable.

- you can run the executables manually as follows:
* `make interp src=examples/prog.src`: builds/runs the interpreter on the source file `examples/prog.src`, outputs the result
* `make compile src=examples/prog.src`: builds/runs the compiler on the source file `examples/prog.src`, outputs the generated assembly code
* `make compile-run src=examples/prog.src`: builds/runs the compiler on the source file `examples/prog.src`, generates the program binary (`examples/prog.run`), and runs it.
* `make compile src=examples/prog.src`: builds/runs the compiler on the source file `examples/prog.src`, outputs the generated redcode

- you can also ask specific files to be built, eg.:
* `make examples/prog.s`: looks up `examples/prog.src`, compiles it, and generates the assembly file `examples/prog.s`
* `make examples/prog.o`: looks up `examples/prog.src`, compiles it, and generates the binary module `examples/prog.o` (unlinked)
* `make examples/prog.run`: looks up `examples/prog.src`, compiles it, assembles, links, and generates the binary executable `examples/prog.run`
* `make examples/prog.s`: looks up `examples/prog.src`, compiles it, and generates the redcode file `examples/prog.s`

You can look at the makefile to see the underlying `dune` commands that are generated, and of course you can use `dune` directly if you find it more convenient.

## Writing tests
## Tests

Tests are written using the [alcotest](https://github.com/mirage/alcotest) unit-testing framework.

Expand Down Expand Up @@ -94,4 +130,8 @@ Remember that to execute your code interactively, use `dune utop` in a terminal,
Documentation for ocaml libraries:
- [containers](http://c-cube.github.io/ocaml-containers/last/) for extensions to the standard library
- [alcotest](https://mirage.github.io/alcotest/alcotest/index.html) for unit-tests
- [BBCTester](https://github.com/pleiad/BBCTester) for blac-box compiler tests
- [BBCStepTester](https://github.com/fabaindaiz/BBCStepTester) for blac-box compiler tests

## Acknowledgements

- Document based on [CC5116](https://users.dcc.uchile.cl/~etanter/CC5116/)
Empty file added TUTORIAL.md
Empty file.
4 changes: 2 additions & 2 deletions bbctests/examples/prog0.bbc
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
NAME: test imp
DESCRIPTION: evaluates a function declaration
SRC:
(MOV 0 1)
(MOV (Dir 0) (Dir 1))
EXPECTED:
;redcode-94b

MOV.I #0 , #1
MOV.I $0 , $1
DAT #0 , #0
12 changes: 6 additions & 6 deletions bbctests/examples/prog1.bbc
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
NAME: test dwarf
DESCRIPTION: evaluates a function declaration
SRC:
(let (x B dest)
(let (x dest)
(seq
(MOV (Dir -1) (place x))
(ADD 4 x)
(MOV (Ins -1) (store x))
(ADD 4 x)
(JMP x)
(label dest) ))
EXPECTED:
;redcode-94b

L1
LET1
MOV.I $-1 , $dest
ADD.AB #4 , $L1
JMP $L1 , #0
ADD.AB #4 , $LET1
JMP $LET1 , #0
dest
DAT #0 , #0
Loading

0 comments on commit d879735

Please sign in to comment.