Skip to content

Commit

Permalink
Merge pull request #281 from koto-lang/more-tweaks
Browse files Browse the repository at this point in the history
More tweaks
  • Loading branch information
irh authored Jan 26, 2024
2 parents 64582d1 + 8546cf0 commit c187068
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 41 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ The Koto project adheres to
exception being thrown.
- Objects can be compared with `null` on the LHS without having to implement
`KotoObject::equal` and/or `not_equal`.
- `map.with_meta_map` has been replaced with `set_meta`, and `get_meta_map` has
been renamed to `get_meta`.

#### API

Expand All @@ -66,11 +68,13 @@ The Koto project adheres to
- The `rc` variant has slightly better performance at the cost of thread
safety.

#### REPL
#### CLI

- The REPL `config.koto` settings have all been moved into a `repl` sub-map.
- e.g.
`export { edit_mode: 'vi' }` is now `export { repl: { edit_mode: 'vi' }}`
- The `--import_tests`/`-T` CLI option will now run tests in the main script
along with any tests from imported modules.

### Removed

Expand Down
4 changes: 2 additions & 2 deletions crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ FLAGS:
-i, --show_instructions Show compiled instructions annotated with source lines
-b, --show_bytecode Show the script's compiled bytecode
-t, --tests Run the script's tests before running the script
-T, --import_tests Run tests when importing modules
-T, --import_tests Run the script's tests, along with any tests in imported modules
-c, --config PATH Config file to load when using the REPL
-v, --version Prints version information
-h, --help Prints help information
Expand Down Expand Up @@ -129,7 +129,7 @@ fn main() -> Result<()> {
}

let koto_settings = KotoSettings {
run_tests: args.run_tests,
run_tests: args.run_tests || args.run_import_tests,
run_import_tests: args.run_import_tests,
..Default::default()
};
Expand Down
8 changes: 5 additions & 3 deletions crates/runtime/src/core_lib/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub fn make_module() -> KMap {
}
});

result.add_fn("get_meta_map", |ctx| {
result.add_fn("get_meta", |ctx| {
let expected_error = "a Map";

match map_instance_and_args(ctx, expected_error)? {
Expand Down Expand Up @@ -325,12 +325,14 @@ pub fn make_module() -> KMap {
}
});

result.add_fn("with_meta_map", |ctx| {
result.add_fn("set_meta", |ctx| {
let expected_error = "two Maps";

match map_instance_and_args(ctx, expected_error)? {
(KValue::Map(data), [KValue::Map(meta)]) => {
Ok(KValue::Map(KMap::from_data_and_meta_maps(data, meta)))
let mut data = data.clone();
data.set_meta_map(meta.meta_map().cloned());
Ok(data.into())
}
(_, unexpected) => type_error_with_slice(expected_error, unexpected),
}
Expand Down
4 changes: 2 additions & 2 deletions crates/runtime/src/types/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ impl KMap {
}

/// Sets the KMap's meta map
pub fn set_meta_map(&mut self, meta: Option<MetaMap>) {
self.meta = meta.map(PtrMut::from)
pub fn set_meta_map(&mut self, meta: Option<PtrMut<MetaMap>>) {
self.meta = meta;
}

/// Returns true if the meta map contains an entry with the given key
Expand Down
8 changes: 4 additions & 4 deletions crates/runtime/tests/vm_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2855,7 +2855,7 @@ catch _
fn arithmetic() {
let script = "
locals = {}
foo = |x| {x}.with_meta_map locals.foo_meta
foo = |x| {x}.set_meta locals.foo_meta
locals.foo_meta =
@+: |other| foo self.x + other.x
@-: |other| foo self.x - other.x
Expand All @@ -2873,7 +2873,7 @@ z.x
fn arithmetic_assignment() {
let script = "
locals = {}
foo = |x| {x}.with_meta_map locals.foo_meta
foo = |x| {x}.set_meta locals.foo_meta
locals.foo_meta =
@+=: |y| self.x += y
@-=: |y| self.x -= y
Expand Down Expand Up @@ -3216,7 +3216,7 @@ x.skip(3).reversed().take(3).to_tuple()
fn basic_access() {
let script = "
locals = {}
foo = |x| {x}.with_meta_map locals.foo_meta
foo = |x| {x}.set_meta locals.foo_meta
locals.foo_meta =
@meta get_x: || self.x
a = foo 10
Expand All @@ -3229,7 +3229,7 @@ a.x + a.get_x()
fn lookup_order() {
let script = "
locals = {}
foo = |x| {x, y: 100}.with_meta_map locals.foo_meta
foo = |x| {x, y: 100}.set_meta locals.foo_meta
locals.foo_meta =
@meta y: 0
a = foo 10
Expand Down
26 changes: 10 additions & 16 deletions docs/core_lib/map.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ check! xyz
- [`map.get`](#get)


## get_meta_map
## get_meta

```kototype
|Map| -> Map
Expand All @@ -139,7 +139,7 @@ my_map =
data: 42
@type: 'My Map'
meta = map.get_meta_map my_map
meta = map.get_meta my_map
print! map.keys(my_map).count()
check! 1
Expand All @@ -152,7 +152,7 @@ check! My Map

### See also

- [`map.with_meta_map`](#with-meta-map)
- [`map.set_meta`](#set-meta)

## insert

Expand Down Expand Up @@ -447,33 +447,27 @@ check! null

- [`map.keys`](#keys)

## with_meta_map
## set_meta

```kototype
|Map, Map| -> Map
```

Returns a Map that contains the data from the first argument, and the Meta Map
from the second argument.
Sets the first argument's meta map to be an instance of the meta map from the
second argument.

### Example

```koto
my_meta =
@type: 'My Meta'
@type: 'MyMeta'
my_data =
foo: 42
x = my_data.with_meta_map my_meta
print! koto.type my_data
check! Map
x = {foo: 42}.set_meta my_meta
print! koto.type x
check! My Meta
check! MyMeta
```

### See also

- [`map.get_meta_map`](#get-meta-map)
- [`map.get_meta`](#get-meta)
12 changes: 6 additions & 6 deletions docs/language/meta_maps.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,20 +280,20 @@ check! ('data')

## Sharing Meta Maps

If you're creating lots of values, then it will likely be more efficient to create a single value with the meta logic, and then share it between values using [`Map.with_meta_map`](../../core/map/#with-meta-map).
If you're creating lots of values, then it will likely be more efficient to create a single map containing the meta logic, and then share it between instances using [`Map.set_meta`](../../core/map/#set-meta).

```koto
# Create an empty map for global values
globals = {}
# Create an empty map for global values
global = {}
# Define a function that makes a Foo
foo = |data|
# Make a map that contains `data`,
# along with the meta map from foo_meta
{data}.with_meta_map globals.foo_meta
# and then assign a shared copy of the meta map from foo_meta
{data}.set_meta global.foo_meta
# Define some meta behaviour in foo_meta
globals.foo_meta =
global.foo_meta =
# Override the + operator
@+: |other| foo self.data + other.data
Expand Down
14 changes: 8 additions & 6 deletions koto/tests/meta_maps.koto
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ globals = {}
# foo acts as a constructor for the Foo type
foo = |x|
# Make a map that contains x, and return its data with the meta map from foo_meta
{x}.with_meta_map globals.foo_meta
{x}.set_meta globals.foo_meta

# Declaring the overloaded operators once and then cloning the meta map into the foo
# instance is more efficient than declaring them each time foo is called.
Expand Down Expand Up @@ -176,17 +176,19 @@ globals.foo_meta =

@test named_meta_entries: ||
f = foo 99
# assert_eq map.keys(f).to_list(), ["x"]
# assert_eq map.size(f), 1

# Map operations aren't inherited by the Foo meta map, so the map module has to be used directly
assert_eq map.keys(f).to_list(), ["x"]
assert_eq map.size(f), 1

assert_eq f.hello, "Hello"
assert_eq f.say_hello("you"), "Hello, you!"

@test get_meta_map: ||
@test get_meta: ||
f = foo 42
meta = map.get_meta_map f
meta = map.get_meta f

# get_meta_map returns a map with the argument's meta map, but no data
# get_meta returns a map with the argument's meta map, but no data
assert_eq map.keys(meta).count(), 0
assert_eq meta.hello, "Hello"

Expand Down
2 changes: 1 addition & 1 deletion libs/color/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub fn make_module() -> KMap {
unexpected => type_error_with_slice("a String", unexpected),
});

result.set_meta_map(Some(meta));
result.set_meta_map(Some(meta.into()));
result
}

Expand Down

0 comments on commit c187068

Please sign in to comment.