Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import system #8

Merged
merged 6 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/target/
Cargo.lock
Cargo.lock
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ serde_json = "1.0.115"
snailquote = "0.3.1"
thiserror = "1.0.58"
tree-sitter = "0.22.5"
tree-sitter-frugurt = "0.0.10"
tree-sitter-frugurt = "0.0.11"
#tree-sitter-frugurt = { path = "../tree-sitter-frugurt" }
#uid = "0.1.7"
macros = { path = "./macros" }
ctor = "0.2.8"

[dev-dependencies]
tempfile = "3.10.1"
Expand Down
40 changes: 24 additions & 16 deletions docs/highlighter/highlighter-info.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
window.highlighterInfo = {
queryString: `"break" @keyword
"commutative" @keyword
"continue" @keyword
"else" @keyword
"fn" @keyword
"if" @keyword
"let" @keyword
"operator" @keyword
"pub" @keyword
"return" @keyword
"struct" @keyword
"static" @keyword
"while" @keyword
"impl" @keyword
queryString: `[
"break"
"class"
"commutative"
"continue"
"data"
"else"
"fn"
"if"
"impl"
"import"
"let"
"operator"
"pub"
"return"
"scope"
"struct"
"static"
"while"
] @keyword

(number_literal) @number
(string_literal) @string
(bool_literal) @bool
(comment) @comment
(bool_literal) @bool
(nah_literal) @nah
(comment) @comment

(let_statement
ident: (identifier) @function.declaration
Expand All @@ -33,6 +40,7 @@ window.highlighterInfo = {
"number": "#2AACB8",
"string": "#6AAB73",
"bool": "#CF8E6D",
"nah": "#CF8E6D",
"comment": "#7A7E85",
},
};
Binary file modified docs/highlighter/tree-sitter-frugurt.wasm
Binary file not shown.
Binary file modified docs/highlighter/tree-sitter.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/src/01-getting-started/02-installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ You can download if from [release page](https://github.com/frugurt-lang/frugurt/

You can build Frugurt from [source code](https://github.com/frugurt-lang/frugurt) on any platform.

Use [Rust Toolchain](https://www.rust-lang.org/tools/install) to build interpreter.
Use [Rust Toolchain](https://www.rust-lang.org/tools/install) to build interpreter.
2 changes: 1 addition & 1 deletion docs/src/02-common-concepts/06-currying.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Currying

You can apply first n arguments to a function to obtain a new function that accepts the rest of the arguments. This is called currying. Curried can be curried as many times as you want.
You can apply first n arguments to a function to make a new function that accepts the rest of the arguments. This is called currying. Curried can be curried as many times as you want.

```frugurt
let add = fn(a, b) {
Expand Down
6 changes: 3 additions & 3 deletions docs/src/03-object-oriented-programming/03-operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ print(a); // Vector{x=4, y=6}

Operator precedences from highest to lowest:

- Custom operators have the highest precedence
- All custom operators
- `**` `<>`
- `*` `/` `%`
- `+` `-`
- `<` `>` `<=` `>=`
- `==` `!=`
- `&&`
- `||` - the lowest precedence
- `||`

All operators have left associativity
All operators are left associative
6 changes: 3 additions & 3 deletions docs/src/03-object-oriented-programming/06-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ v.Length = 1;
print(v); // Vec { x: 0.6, y: 0.8 }
```

In this example, Vec has a "property" Length, that is freely computable from other fields.
In this example, Vec has a "property" Length that is easily computable from other fields.
Like methods, properties can access fields, methods and other properties of the object.
`(new_length)` can be omitted, in which case the default identifier `value` is used.
Properties can be static.
Expand All @@ -34,7 +34,7 @@ Also, there is no need to implement `get` and `set` every time.
```frugurt
class Time {
static time = 0;

pub static Now {
get { time } // this is equivalent to `get => time;`
}
Expand All @@ -44,5 +44,5 @@ print(Time.Now);
```

In this example, imagine game engine.
Static field time is updated by game engine every frame, and public property `Now` can be used to obtain current time
Static field time is updated by game engine every frame, and public property `Now` can be used to get current time
on the user side.
3 changes: 3 additions & 0 deletions docs/src/04-scope-manipulation/01-index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Scope manipulation

Frugurt supports explicit scope capturing and subsequent manipulation.
35 changes: 35 additions & 0 deletions docs/src/04-scope-manipulation/02-scope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Scope keyword

Scope keyword can be used in three constructs:

- `scope()` - captures scope in which it was evaluated
- `scope s { statements... }` - run statements in specified scope
- `scope s { statements... expression }` - run statements in specified scope and return result of expression

Example:

```frugurt
let f = fn () {
let a = 5;
let b = 3;
scope()
};

let scope_object = f();

print(scope_object.a); // 5

scope scope_object {
// this statement is executed in the same scope as the body of function f ran
// so the variables a and b are available here
print(a * b); // 15
}

scope_object.a = 10; // old variables can be re-assigned
scope_object.c = 20; // new variables can be declared

print(scope scope_object {
let r = a + c;
r * b
}); // 90
```
29 changes: 29 additions & 0 deletions docs/src/04-scope-manipulation/03-imports.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Imports

Other files can be imported into your code by using the `import` expression.
Import expression returns the same scope object, which was mentioned in the previous chapter.

Example:

`main.fru`
```frugurt
let foo = import "foo.fru";

print(foo.f(1, 2)); // 3

// this is as badass as extremely stupid
scope foo {
let wow = 5;

print(omg()); // 5
}
```

`foo.fru`
```frugurt
let f = fn(x, y) {
x + y
};

let omg = fn() { wow };
```
3 changes: 3 additions & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@
- [Methods](./03-object-oriented-programming/04-methods.md)
- [Statics](./03-object-oriented-programming/05-statics.md)
- [Properties](./03-object-oriented-programming/06-properties.md)
- [Scope manipulation](./04-scope-manipulation/01-index.md)
- [Scope keyword](./04-scope-manipulation/02-scope.md)
- [Imports](./04-scope-manipulation/03-imports.md)
2 changes: 2 additions & 0 deletions macros/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target/
Cargo.lock
11 changes: 11 additions & 0 deletions macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "macros"
version = "0.1.0"
edition = "2021"

[lib]
proc-macro = true

[dependencies]
syn = "2.0.66"
quote = "1.0.36"
27 changes: 27 additions & 0 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use proc_macro::TokenStream;
use std::hash::{DefaultHasher, Hash, Hasher};

use quote::quote;
use syn::LitStr;

#[proc_macro]
pub fn static_ident(input: TokenStream) -> TokenStream {
let ast: LitStr = syn::parse(input).unwrap();

let ident = ast.value();

let mut hasher = DefaultHasher::new();
ident.hash(&mut hasher);
let hashed_ident = hasher.finish();

quote! {
{
#[ctor::ctor]
fn ident_ctor() {
Identifier::new(#ident);
}
Identifier::new_unchecked(#hashed_ident)
}
}
.into()
}
1 change: 1 addition & 0 deletions obsidian/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/.obsidian
12 changes: 12 additions & 0 deletions obsidian/FIXME.canvas
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"nodes":[
{"id":"813b32f2728a4a94","type":"group","x":-800,"y":-440,"width":640,"height":820,"label":"ordinary"},
{"id":"e6b12e213f195739","type":"group","x":-1420,"y":-440,"width":520,"height":500,"label":"critical"},
{"id":"02fe9a5b84622932","type":"text","text":"`fru_clone()` horror","x":-1400,"y":-414,"width":250,"height":79},
{"id":"cd9a0d2eaf046fee","type":"text","text":"implement Display for FruValue and fix for FruObject","x":-740,"y":-409,"width":250,"height":110},
{"id":"b18a8755b912d870","type":"text","text":"remove or fix BACKWARDS_MAP in Identifier (fails testing with some probability) !! probably already fixed","x":-740,"y":-260,"width":305,"height":170},
{"id":"8b8b22b9de04c759","type":"text","text":"automate wasm module for book","x":-740,"y":-60,"width":250,"height":60},
{"id":"4cbdbc839acac840","type":"text","text":"make set expression, not statement","x":-740,"y":40,"width":250,"height":60}
],
"edges":[]
}
25 changes: 25 additions & 0 deletions obsidian/TODO.canvas
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"nodes":[
{"id":"0c274527d795ce38","type":"group","x":-80,"y":600,"width":400,"height":400,"label":"OPTIMIZATIONS"},
{"id":"0e8289b07d6ca556","type":"group","x":-600,"y":600,"width":400,"height":380,"label":"CI/CD"},
{"id":"070a7b543247f7a2","type":"text","text":"simplified syntax for read-only properties","x":-290,"y":360,"width":250,"height":60},
{"id":"5d4e5bd937436926","type":"text","text":"computed properties","x":-640,"y":360,"width":250,"height":60,"color":"4"},
{"id":"1c18b7117da43e6e","type":"text","text":"\"evil\" features","x":-460,"y":-180,"width":250,"height":67,"color":"4"},
{"id":"41499d9f6eafdeec","type":"text","text":"trait polymorphism for native types","x":-460,"y":-40,"width":250,"height":60,"color":"4"},
{"id":"4ab66adbfddd4d15","type":"text","text":"scope manipulation features","x":-80,"y":-180,"width":250,"height":60,"color":"4"},
{"id":"aa2bea5c494cbddd","type":"text","text":"add traceback for errors","x":-160,"y":252,"width":250,"height":60},
{"id":"550b9c0e5c7cd03a","type":"text","text":"derivation and implicit derivation, and make them overridable (the main reason is equality of objects)","x":620,"y":300,"width":250,"height":160},
{"id":"97a68fbd25b52ede","type":"text","text":"destructuring let statements","x":800,"y":160,"width":250,"height":60},
{"id":"feb6594a9d261a54","type":"text","text":"modules and imports\n- [ ] tests\n- [x] import as expression","x":260,"y":-180,"width":250,"height":120,"color":"3"},
{"id":"18df0d00841f02bd","type":"text","text":"collections\n- [ ] list\n- [ ] set\n- [ ] map\n- [ ] tuple?","x":-80,"y":0,"width":250,"height":182,"color":"3"},
{"id":"b9c4b54397d2bf2d","type":"text","text":"macro for computing hash of ident in compile time","x":-40,"y":660,"width":250,"height":87,"color":"4"},
{"id":"b9e932828d9a3c13","type":"text","text":"make cd for windows and linux releases","x":-580,"y":640,"width":250,"height":60}
],
"edges":[
{"id":"4f43eea514ca8881","fromNode":"41499d9f6eafdeec","fromSide":"right","toNode":"4ab66adbfddd4d15","toSide":"left"},
{"id":"94361d23f182cbe8","fromNode":"4ab66adbfddd4d15","fromSide":"right","toNode":"feb6594a9d261a54","toSide":"left"},
{"id":"e3e0be30be175453","fromNode":"1c18b7117da43e6e","fromSide":"right","toNode":"4ab66adbfddd4d15","toSide":"left"},
{"id":"8706d0e0442108f4","fromNode":"41499d9f6eafdeec","fromSide":"right","toNode":"18df0d00841f02bd","toSide":"left"},
{"id":"10698732105d19f9","fromNode":"5d4e5bd937436926","fromSide":"right","toNode":"070a7b543247f7a2","toSide":"left"}
]
}
7 changes: 7 additions & 0 deletions obsidian/TOTHINK.canvas
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"nodes":[
{"id":"1ac37b84ff817ecc","x":-733,"y":-605,"width":473,"height":165,"type":"text","text":"Issue 1:\nIf curried function mutates one of it's arguments, should subsequent calls receive mutated value or should it be cloned on call?"},
{"id":"901340d58aa31311","type":"text","text":"introduce new wrapper extensions like `wrap_ok`, `wrap_err`, `wrap_value`","x":-720,"y":-220,"width":250,"height":130}
],
"edges":[]
}
2 changes: 0 additions & 2 deletions rust-toolchain.toml

This file was deleted.

20 changes: 20 additions & 0 deletions src/interpreter/ast_helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use std::rc::Rc;

use crate::interpreter::{
expression::FruExpression, identifier::Identifier, statement::FruStatement,
value::function::FormalParameters,
};

#[derive(Debug, Clone)]
pub struct RawStaticField {
pub ident: Identifier,
pub value: Option<Box<FruExpression>>,
}

#[derive(Debug, Clone)]
pub struct RawMethod {
pub is_static: bool,
pub ident: Identifier,
pub parameters: FormalParameters,
pub body: Rc<FruStatement>,
}
Loading
Loading