Skip to content
Draft
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
34 changes: 17 additions & 17 deletions COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,24 +170,24 @@ I see a module in the code repo that is labelled the IO library, but it only cre

| Status | Function | Differences | Notes |
| ------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ----- |
| ⚫️ | `close([file])` | | |
| ⚫️ | `flush()` | | |
| ⚫️ | `input([file])` | | |
| ⚫️ | `lines([filename, args...])` | | |
| ⚫️ | `open(filename [, mode])` | | |
| | `output([file])` | | |
| 🔵 | `close([file])` | | |
| 🔵 | `flush()` | | |
| 🔵 | `input([file])` | | |
| 🔵 | `lines([filename, args...])` | | |
| 🔵 | `open(filename [, mode])` | | |
| 🔵 | `output([file])` | | |
| ⚫️/❗ | `popen(prog[, mode])` | Might be classifiable as "C weirdness" or it's just creating another process which kinda feels as icky as the OS module imo | |
| ⚫️ | `read(args...)` | | |
| ⚫️ | `tmpfile()` | | |
| ⚫️ | `type(obj)` | | |
| ⚫️ | `write(args...)` | | |
| ⚫️ | `file:close()` | | |
| ⚫️ | `file:flush()` | | |
| ⚫️ | `file:lines(args...)` | | |
| ⚫️ | `file:read(args...)` | | |
| ⚫️ | `file:seek([whence, offset])` | | |
| ⚫️ | `file:setvbuf(mode[, size])` | | |
| ⚫️ | `file:write(args...)` | | |
| 🔵 | `read(args...)` | | |
| 🔵 | `tmpfile()` | | |
| 🔵 | `type(obj)` | | |
| 🔵 | `write(args...)` | | |
| 🔵 | `file:close()` | | |
| 🔵 | `file:flush()` | | |
| 🔵 | `file:lines(args...)` | | |
| 🔵 | `file:read(args...)` | | |
| 🔵 | `file:seek([whence, offset])` | | |
| ⚫️/❗ | `file:setvbuf(mode[, size])` | I think it's better not to touch this because it would require `libc` and `winapi`. | |
| 🔵 | `file:write(args...)` | | |

## OS

Expand Down
29 changes: 28 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ gc-arena = { git = "https://github.com/kyren/gc-arena", rev = "5a7534b883b703f23
hashbrown = { version = "0.14", features = ["raw"] }
rand = { version = "0.8", features = ["small_rng"] }
serde = "1.0"
tempfile = "3"
either = "1"
thiserror = "1.0"

piccolo = { path = "./", version = "0.3.3" }
Expand All @@ -44,6 +46,8 @@ anyhow.workspace = true
gc-arena.workspace = true
hashbrown.workspace = true
rand.workspace = true
tempfile.workspace = true
either.workspace = true
thiserror.workspace = true

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ very much WIP, so ensuring this is done correctly is an ongoing effort.
## What currently doesn't work

* A large amount of the stdlib is not implemented yet. Most "peripheral" parts
of the stdlib are this way, the `io`, `file`, `os`, `package`, `string`,
of the stdlib are this way, the `os`, `package`, `string`,
`table`, and `utf8` libs are either missing or very sparsely implemented.
* There is no support yet for finalization. `gc-arena` supports finalization in
such a way now that it should be possible to implement `__gc` metamethods with
Expand Down
6 changes: 6 additions & 0 deletions src/lua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ impl<'gc> Context<'gc> {
self.state.finalizers
}

pub fn io_metatable(self) -> Table<'gc> {
self.state.io_metatable
}

// Calls `ctx.globals().get(key)`
pub fn get_global<V: FromValue<'gc>>(self, key: &'static str) -> Result<V, TypeError> {
self.state.globals.get(self, key)
Expand Down Expand Up @@ -298,6 +302,7 @@ struct State<'gc> {
registry: Registry<'gc>,
strings: InternedStringSet<'gc>,
finalizers: Finalizers<'gc>,
io_metatable: Table<'gc>,
}

impl<'gc> State<'gc> {
Expand All @@ -307,6 +312,7 @@ impl<'gc> State<'gc> {
registry: Registry::new(mc),
strings: InternedStringSet::new(mc),
finalizers: Finalizers::new(mc),
io_metatable: Table::new(mc),
}
}

Expand Down
10 changes: 9 additions & 1 deletion src/meta_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use gc_arena::Collect;
use thiserror::Error;

use crate::async_callback::{AsyncSequence, Locals};
use crate::stdlib::IoFile;
use crate::{async_sequence, SequenceReturn, Stack};
use crate::{
table::InvalidTableKey, Callback, CallbackReturn, Context, Function, IntoValue, Table, Value,
Expand Down Expand Up @@ -203,6 +204,13 @@ pub fn index<'gc>(

idx
}
Value::UserData(u) if u.downcast_static::<IoFile>().is_ok() => {
let idx = ctx.io_metatable().get_value(ctx, MetaMethod::Index);
if idx.is_nil() {
return Ok(MetaResult::Value(Value::Nil));
}
idx
}
Comment on lines +207 to +213
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be handled by the existing UserData code, by setting the metatable for the file UserData objects with UserData::set_metatable. (As such, the global io_metatable does not need to exist.)

Value::UserData(u) if u.metatable().is_some() => {
let idx = if let Some(mt) = u.metatable() {
mt.get_value(ctx, MetaMethod::Index)
Expand All @@ -223,7 +231,7 @@ pub fn index<'gc>(
return Err(MetaOperatorError::Unary(
MetaMethod::Index,
table.type_name(),
))
));
}
};

Expand Down
Loading