Skip to content

Commit 6880162

Browse files
committed
Merge branch 'master' into method_impl
2 parents 2052c1e + 67dafe9 commit 6880162

14 files changed

+489
-38
lines changed

.github/workflows/doc.yml

+9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ on:
55
pull_request:
66
branches: [ master ]
77

8+
env:
9+
toolchain-version: 1.53.0
10+
llvm-version: "11.0.1"
11+
812
jobs:
913
cargo-docs:
1014
runs-on: ubuntu-latest
@@ -19,6 +23,11 @@ jobs:
1923
uses: peaceiris/actions-mdbook@v1
2024
with:
2125
mdbook-version: 'latest'
26+
- name: Install LLVM
27+
uses: ghaith/install-llvm-action@latest
28+
with:
29+
version: ${{ env.llvm-version }}
30+
directory: "./llvm"
2231
- name: Build API documentation
2332
uses: actions-rs/cargo@v1
2433
with:

.github/workflows/rust.yml

+7
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ jobs:
3333
uses: ghaith/install-llvm-action@latest
3434
with:
3535
version: ${{ env.llvm-version }}
36+
directory: "./llvm"
3637

3738
- name: Cargo check
3839
uses: actions-rs/cargo@v1
@@ -114,6 +115,12 @@ jobs:
114115
override: true
115116
components: clippy, rustfmt
116117

118+
- name: Install LLVM
119+
uses: ghaith/install-llvm-action@latest
120+
with:
121+
version: ${{ env.llvm-version }}
122+
directory: "./llvm"
123+
117124
- name: Run cargo fmt
118125
uses: actions-rs/cargo@v1
119126
with:

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
*.ir
66
*.o
77
*.bc
8+
*.a
9+
*.elf

Cargo.lock

+31-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ glob = "0.3.0"
2121
encoding_rs = "0.8"
2222
encoding_rs_io = "0.1"
2323
codespan-reporting = "0.11.1"
24+
mun_lld = "110.0.0"
2425

2526

2627
[lib]

book/src/build_and_install.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## Prerequisites
44
To be able to build the source code, you will need to [install Rust](https://www.rust-lang.org/tools/install)
55
and LLVM 11, along with the standard build tools (`build-essential`) and `libz-dev` on your machine.
6-
For Linux the package manager version of LLVM (e.g. `llvm-11-dev` for apt) will work fine, for Windows, you need a
6+
For Linux the package manager version of LLVM (e.g. `llvm-11-dev`, `liblld-11-dev` for apt) will work fine, for Windows, you need a
77
[special build](https://github.com/ghaith/llvm-package-windows/releases/tag/v11.0.1). If you want to
88
clone and work on the repository, you'll also need _git_.
99

book/src/intro_1.md

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ puts out static or shared objects as well as LLVM IR or bitcode by the flip of
88
a command line flag. We are aiming towards an open-source industry-grade ST compiler
99
supporting at least the features in 2nd edition IEC 61131 standard.
1010

11+
You might also want to refer to the [API documentation](https://ghaith.github.io/rusty/api/rusty/).
12+
1113
## Supported Language Concepts
1214
### POUs
1315
- ✔ Program
@@ -40,13 +42,15 @@ supporting at least the features in 2nd edition IEC 61131 standard.
4042
- ✔ Call statements
4143
- ✔ Implicit call arguments
4244
- ✔ Explicit call arguments
45+
- ✔ EXIT, CONTINUE statements
4346

4447
### Control Structures
4548
- ✔ IF Statement
4649
- ✔ CASE Statement
4750
- ✔ FOR Loops
4851
- ✔ WHILE Loops
4952
- ✔ REPEAT Loops
53+
- ✔ RETURN statement
5054

5155
### Expressions
5256
- ✔ Arithmetic Operators

book/src/using_rusty.md

+46-5
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,53 @@ More examples:
2222
- `rustyc --ir src/*.st` will compile all st files in the src-folder.
2323
- `rustyc --ir "**/*.st"` will compile all st-files in the current folder and its subfolders recursively.
2424

25-
## Compiling a static object
25+
## Example: Building a hello world program
26+
### Writing the code
27+
We want to print something to the terminal, so we're going to declare external functions
28+
for that and link with libc when we're done. This program can also be found at
29+
`examples/hello_world.st` in the source tree of Rusty.
2630

27-
## Compiling a linkable object
31+
* `_start` is our entry point to the program, because most linker scripts define it this way.
2832

29-
## Creating a shared library
33+
* Since we don't have a `crt0` right now, we have to call the `exit()` function by ourselves after we're
34+
done. Otherwise, the program will most likely crash (because it tries to return to a function that never
35+
existed).
3036

31-
## Linking with an external application
37+
```st
38+
@EXTERNAL FUNCTION puts : DINT
39+
VAR_INPUT
40+
text : STRING;
41+
END_VAR
42+
END_FUNCTION
3243
33-
## Writing a main
44+
@EXTERNAL FUNCTION exit : DINT
45+
VAR_INPUT
46+
status : DINT;
47+
END_VAR
48+
END_FUNCTION
49+
50+
FUNCTION _start : DINT
51+
puts('hello, world!');
52+
exit(0);
53+
END_FUNCTION
54+
```
55+
56+
### Compiling with rusty
57+
Compiling with rusty is very easy. If you just want to build an object file, then do this:
58+
```bash
59+
rustyc -c hello_world.st -o hello_world.o
60+
```
61+
62+
### Linking an executable
63+
Instead, you can also compile this into an executable and run it:
64+
```bash
65+
rustyc hello_world.st -o hello_world -L/path/to/libs -lc
66+
./hello_world
67+
```
68+
69+
Please note that RuSTy will attempt to link the generated object file by default to generate
70+
an executable if you didn't specify something else (option `-c`).
71+
* The `-lc` flag tells the linker it should link against `libc`. Depending on the available libraries on your system,
72+
the linker will prefer a dynamically linked library if available, and revert to a static one otherwise.
73+
* You add library search pathes by providing additional `-L /path/...` options. By default, this will be
74+
the current directory.

examples/hello_world.st

+7-8
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ VAR_INPUT
44
END_VAR
55
END_FUNCTION
66

7-
@EXTERNAL FUNCTION exit : __VOID
8-
VAR_INPUT status : DINT; END_VAR
9-
END_FUNCTION
10-
11-
FUNCTION main : DINT
12-
puts('hello, world');
7+
@EXTERNAL FUNCTION exit : DINT
8+
VAR_INPUT
9+
status : DINT;
10+
END_VAR
1311
END_FUNCTION
1412

1513
FUNCTION _start : DINT
16-
exit(main(0));
17-
END_FUNCTION
14+
puts('hello, world!');
15+
exit(0);
16+
END_FUNCTION

src/cli.rs

+56-8
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ pub struct CompileParameters {
6262
)]
6363
pub output_bit_code: bool,
6464

65+
#[structopt(short = "c", help = "Do not link after compiling object code")]
66+
pub skip_linking: bool,
67+
6568
#[structopt(
6669
long,
6770
name = "target-triple",
@@ -85,6 +88,17 @@ pub struct CompileParameters {
8588
)]
8689
// having a vec allows bash to resolve *.st itself
8790
pub input: Vec<String>,
91+
92+
#[structopt(
93+
name = "library-path",
94+
long,
95+
short = "L",
96+
help = "Search path for libraries, used for linking"
97+
)]
98+
pub library_pathes: Vec<String>,
99+
100+
#[structopt(name = "library", long, short = "l", help = "Library name to link")]
101+
pub libraries: Vec<String>,
88102
}
89103

90104
fn parse_encoding(encoding: &str) -> Result<&'static Encoding, String> {
@@ -122,20 +136,21 @@ impl CompileParameters {
122136

123137
/// return the output filename with the correct ending
124138
pub fn output_name(&self) -> Option<String> {
139+
let out_format = self.output_format_or_default();
125140
if let Some(n) = &self.output {
126141
Some(n.to_string())
127142
} else {
128-
let ending = match self.output_format_or_default() {
129-
FormatOption::Bitcode => "bc",
130-
FormatOption::Static => "o",
131-
FormatOption::Shared => "so",
132-
FormatOption::PIC => "so",
133-
FormatOption::IR => "ir",
143+
let ending = match out_format {
144+
FormatOption::Bitcode => ".bc",
145+
FormatOption::Static if self.skip_linking => ".o",
146+
FormatOption::Static => "",
147+
FormatOption::Shared | FormatOption::PIC => ".so",
148+
FormatOption::IR => ".ir",
134149
};
135150

136151
let output_name = self.input.first().unwrap();
137152
let basename = Path::new(output_name).file_stem()?.to_str()?;
138-
Some(format!("{}.{}", basename, ending))
153+
Some(format!("{}{}", basename, ending))
139154
}
140155
}
141156
}
@@ -234,13 +249,17 @@ mod cli_tests {
234249
assert_eq!(parameters.output_name().unwrap(), "charlie.so".to_string());
235250

236251
let parameters =
237-
CompileParameters::parse(vec_of_strings!("examples/test/delta.st", "--static"))
252+
CompileParameters::parse(vec_of_strings!("examples/test/delta.st", "--static", "-c"))
238253
.unwrap();
239254
assert_eq!(parameters.output_name().unwrap(), "delta.o".to_string());
240255

241256
let parameters =
242257
CompileParameters::parse(vec_of_strings!("examples/test/echo", "--bc")).unwrap();
243258
assert_eq!(parameters.output_name().unwrap(), "echo.bc".to_string());
259+
260+
let parameters =
261+
CompileParameters::parse(vec_of_strings!("examples/test/echo.st")).unwrap();
262+
assert_eq!(parameters.output_name().unwrap(), "echo".to_string());
244263
}
245264

246265
#[test]
@@ -338,6 +357,35 @@ mod cli_tests {
338357
assert_eq!(parameters.output_shared_obj, false);
339358
}
340359

360+
#[test]
361+
fn library_path_added() {
362+
let parameters = CompileParameters::parse(vec_of_strings!(
363+
"input.st",
364+
"--library-path",
365+
"xxx",
366+
"-L",
367+
"test",
368+
"-L.",
369+
"-L/tmp"
370+
))
371+
.unwrap();
372+
assert_eq!(parameters.library_pathes, vec!["xxx", "test", ".", "/tmp"]);
373+
}
374+
375+
#[test]
376+
fn libraries_added() {
377+
let parameters = CompileParameters::parse(vec_of_strings!(
378+
"input.st",
379+
"-l",
380+
"test",
381+
"-lc",
382+
"--library",
383+
"xx"
384+
))
385+
.unwrap();
386+
assert_eq!(parameters.libraries, vec!["test", "c", "xx"]);
387+
}
388+
341389
#[test]
342390
fn cli_supports_version() {
343391
match CompileParameters::parse(vec_of_strings!("input.st", "--version")) {

src/compile_error.rs

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ pub enum CompileError {
3939

4040
#[error("Cannot write File {path:}: {reason:}")]
4141
IoWriteError { path: String, reason: String },
42+
43+
#[error("Cannot link: {reason:}")]
44+
LinkerError { reason: String },
4245
}
4346

4447
impl From<Diagnostic> for CompileError {

0 commit comments

Comments
 (0)