Skip to content

Commit

Permalink
Merge pull request #2 from antoniusnaumann/refactor/tree-sitter-parser
Browse files Browse the repository at this point in the history
Refactor/tree sitter parser
  • Loading branch information
antoniusnaumann authored Aug 7, 2024
2 parents 3aec61f + 5ee3922 commit dfbb669
Show file tree
Hide file tree
Showing 100 changed files with 3,057 additions and 2,613 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/CI.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: 'true'
- name: Check
run: cargo check --workspace --verbose
- name: Build
run: cargo build --workspace --verbose
- name: Test
run: cargo test --workspace --verbose
run: cargo test --workspace --verbose
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
/.idea/
.DS_Store
__*/
temp/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "tree-sitter-galvan"]
path = tree-sitter-galvan
url = https://github.com/antoniusnaumann/tree-sitter-galvan
21 changes: 13 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ license = "MIT"
galvan-ast = { path = "galvan-ast", version = "0.0.0-dev09" }
# galvan-core = { path = "galvan-core", version = "0.0.0-dev09" }
galvan-files = { path = "galvan-files", version = "0.0.0-dev09" }
galvan-pest = { path = "galvan-pest", version = "0.0.0-dev09" }
galvan-test-macro = { path = "galvan-test-macro", version = "0.0.0-dev09" }
galvan-ast-macro = { path = "galvan-ast-macro", version = "0.0.0-dev09"}
galvan-resolver = { path = "galvan-resolver", version = "0.0.0-dev09" }
galvan-into-ast = { path = "galvan-into-ast", version = "0.0.0-dev09" }
galvan-parse = { path = "galvan-parse", version = "0.0.0-dev09" }

thiserror = "1.0.51"
itertools = "0.12.0"
thiserror = "1.0.61"
itertools = "0.13.0"

[package]
name = "galvan"
Expand All @@ -26,8 +28,8 @@ license.workspace = true

[dependencies]
galvan-transpiler = { path = "galvan-transpiler", version = "0.0.0-dev09" }
itertools = "0.12.0"
anyhow = "1.0.79"
itertools = "0.13.0"
anyhow = "1.0.86"

[features]
build = ["galvan-transpiler/exec"]
Expand All @@ -37,12 +39,15 @@ build = ["galvan-transpiler/exec"]
[workspace]
resolver = "2"
members = [
"galvan-ast-macro",
"galvan-ast",
"galvan-into-ast",
"galvan-parse",
# "galvan-core",
"galvan-files",
"galvan-pest",
"galvan-resolver",
"galvan-transpiler",
"galvan-test-macro",
"galvan-test"
]
"galvan-test",
"tree-sitter-galvan",
]
45 changes: 38 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ Types in Galvan are defined with the `type` keyword.
```rust
/// A struct definition
pub type Color {
r: Int
g: Int
r: Int,
g: Int,
b: Int
}

Expand Down Expand Up @@ -101,6 +101,25 @@ main {
}
```

### Default Values
> [!WARNING]
> Default values are not implemented yet
Struct types in Galvan can allow ommitting certain attributes when created with the default initializer. To do so,

```rust
type Book {
title: String = "Lorem Ipsum"
content: String = "Lorem ipsum dolor sit amet..."
}

main {
let book = Book()
}
```

In case the type can be constructed without arguments, Rust's `Default` trait is automatically implemented.

### Collections

Galvan features syntactic sugar for collection types:
Expand All @@ -124,11 +143,11 @@ type FileOrIoErr = File!IoError
The error variant is specified after the `!` symbol. If it is not given, a flexible error type is used.

> [!WARNING]
> `!`, `?` and `??` are not implemented yet
> `!` and `?` are not implemented yet
```rust
fn open_file(path: String) -> File! {
let file = File::open(path)!
let contents = file.read_to_string()?.find("foo")?.uppercase() ?? ""
let contents = file.read_to_string()?.find("foo")?.uppercase() else { "" }

contents
}
Expand All @@ -137,7 +156,7 @@ fn open_file(path: String) -> File! {

`?` is the safe call operator in Galvan. The subsequent expression is only evaluated if the result is not an error and not none.

`??` is the null-coalescing operator, you can use it to provide a default if the left-hand side expression is none. The right-hand side of the null-coalescing operator cannot be a return or throw expression.
`else` can also be used as the null-coalescing operator (since you can use else after every expression that is an optional or a result type), you can use it to provide a default if the left-hand side expression is none.

### Union Types
Galvan supports union types everywhere where a type identifier is expected:
Expand Down Expand Up @@ -195,8 +214,8 @@ fn grow(mut self: Dog) {
References that are allowed to be stored in structs have to be declared as heap references. This is done by prefixing the declaration with `ref`:
```rust
pub type Person {
name: String
age: Int
name: String,
age: Int,
// This is a heap reference
ref dog: Dog
}
Expand Down Expand Up @@ -409,6 +428,11 @@ Collection operators:
- `[:]`: Slicing
- `in`, `∈`, `∊`: Membership
Range operators:
- `..<`: Exclusive Range
- `..=`: Inclusive Range
- `+-`, `±`: Inclusive Range around a value (tolerance)
#### Unicode and Custom Operators
Galvan supports Unicode and custom operators:
> [!WARNING]
Expand Down Expand Up @@ -494,3 +518,10 @@ test "Ensure that addition works correctly" {
}
```
Like 'main', 'test' is not a function but an entry point. Tests can take a string as a description. Although this is optional, adding a brief description to your unit tests is highly encouraged.
## Semicolon Inference
While Galvan uses semicolons to separate statements, Galvan infers semicolons on newlines when:
- the next line starts with an alpha-character (or an underscore) as the first non-whitespace character
- the next line starts with `{`, `(`, `[`, or `'`, `"` as the first non-whitespace character

Regardless of the rules above, Galvan does not infer a semicolon when the current line itself is not a valid statement.
10 changes: 3 additions & 7 deletions example-code/empty.galvan
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/*# AST
empty()
*/

/*# TRANSPILE
""
*/
//@TRANSPILE
//""
//@end
12 changes: 4 additions & 8 deletions example-code/functions/empty_function.galvan
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
/*# AST
single(function(inherited(), "empty", params(vec![]), None, empty_body()))
*/
//@TRANSPILE
// "pub(crate) fn empty() { }"
//@end

/*# TRANSPILE
"pub(crate) fn empty() { }"
*/

fn empty() {}
fn empty() {}
14 changes: 6 additions & 8 deletions example-code/functions/function_call.galvan
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/*# TRANSPILE
// TODO: Remove the reference &a for copy types by type checking function signatures
// TODO: Only insert & around expressions for non-copy types
"
pub fn multiply(a: i64, b: i64) -> i64 { a * b }
pub fn double(a: i64) -> i64 { multiply(a, 2) }
"
*/
//@TRANSPILE
// "
// pub fn multiply(a: i64, b: i64) -> i64 { a * b }
// pub fn double(a: i64) -> i64 { multiply(a, 2) }
// "
//@end

pub fn multiply(a: Int, b : Int) -> Int {
a * b
Expand Down
36 changes: 10 additions & 26 deletions example-code/functions/member_function.galvan
Original file line number Diff line number Diff line change
@@ -1,28 +1,12 @@
/*# AST
multi(vec![
empty_type(inherited(), "Dog").into(),
function(
inherited(),
"woof",
params(
vec![
(None, "self", plain("Dog")),
]),
None,
empty_body()
).into()
])
*/

/*# TRANSPILE
"
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct Dog;
impl Dog {
pub(crate) fn woof(&self) { }
}
"
*/
//@TRANSPILE
//"
//#[derive(Clone, Debug, PartialEq)]
//pub(crate) struct Dog;
//impl Dog {
//pub(crate) fn woof(&self) { }
//}
//"
//@end
type Dog

fn woof(self: Dog) { }
fn woof(self: Dog) { }
32 changes: 8 additions & 24 deletions example-code/functions/mut_param_function.galvan
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
/*# AST
multi(vec![
empty_type(inherited(), "Dog").into(),
function(
inherited(),
"bark",
params(
vec![
(Some(Mut.into()), "dog", plain("Dog")),
]),
None,
empty_body()
).into()
])
*/

/*# TRANSPILE
"
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct Dog;
pub(crate) fn bark(dog: &mut Dog) { }
"
*/
//@TRANSPILE
//"
//#[derive(Clone, Debug, PartialEq)]
//pub(crate) struct Dog;
//pub(crate) fn bark(dog: &mut Dog) { }
//"
//@end
type Dog

fn bark(mut dog: Dog) { }
fn bark(mut dog: Dog) { }
32 changes: 8 additions & 24 deletions example-code/functions/ref_param_function.galvan
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
/*# AST
multi(vec![
empty_type(inherited(), "Dog").into(),
function(
inherited(),
"bark",
params(
vec![
(Some(Ref.into()), "dog", plain("Dog")),
]),
None,
empty_body()
).into()
])
*/

/*# TRANSPILE
"
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct Dog;
pub(crate) fn bark(dog: std::sync::Arc<std::sync::Mutex<Dog>>) { }
"
*/
//@TRANSPILE
//"
//#[derive(Clone, Debug, PartialEq)]
//pub(crate) struct Dog;
//pub(crate) fn bark(dog: std::sync::Arc<std::sync::Mutex<Dog>>) { }
//"
//@end
type Dog

fn bark(ref dog: Dog) { }
fn bark(ref dog: Dog) { }
24 changes: 4 additions & 20 deletions example-code/functions/simple_function.galvan
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
/*# AST
single(
function(
public(),
"add",
params(
vec![
(None, "a", plain("Int")),
(None, "b", plain("Int"))
]),
Some(plain("Int")),
empty_body()
)
)
*/

/*# TRANSPILE
"pub fn add(a: i64, b: i64) -> i64 { }"
*/
//@TRANSPILE
//"pub fn add(a: i64, b: i64) -> i64 { }"
//@end

pub fn add(a: Int, b: Int) -> Int {
// a + b
}
}
12 changes: 6 additions & 6 deletions example-code/inference/vec.galvan
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/*# TRANSPILE
"
pub(crate) fn __main__() {
let a: ::std::vec::Vec<_> = vec![1, 2, 3];
}"
*/
//@TRANSPILE
//"
//pub(crate) fn __main__() {
// let a: ::std::vec::Vec<_> = vec![1, 2, 3];
//}"
//@end

main {
let a = [1, 2, 3]
Expand Down
12 changes: 4 additions & 8 deletions example-code/types/array_type.galvan
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
/*# AST
single(alias_type(inherited(), "IntArray", array(plain("Int"))))
*/
//@TRANSPILE
//"pub(crate) type IntArray = ::std::vec::Vec<i64>;"
//@end

/*# TRANSPILE
"pub(crate) type IntArray = ::std::vec::Vec<i64>;"
*/

type IntArray = [Int]
type IntArray = [Int]
12 changes: 4 additions & 8 deletions example-code/types/empty_struct_type.galvan
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
/*# AST
single(struct_type(inherited(), "EmptyStruct", vec![]))
*/
//@TRANSPILE
//"#[derive(Clone, Debug, PartialEq)] pub(crate) struct EmptyStruct { }"
//@end

/*# TRANSPILE
"#[derive(Clone, Debug, PartialEq)] pub(crate) struct EmptyStruct { }"
*/

type EmptyStruct {}
type EmptyStruct {}
Loading

0 comments on commit dfbb669

Please sign in to comment.