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

Named parameters #141

Merged
merged 8 commits into from
Dec 2, 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
18 changes: 11 additions & 7 deletions docs/config/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@ const example = `event MyEvent = {
from: Server,
type: Reliable,
call: ManyAsync,
data: struct {
foo: string,
bar: u8,
},
data: (Foo: boolean, Bar: u32, Baz: string)
}`

const dataExample = `event MyEvent = {
const dataExample = `event OneUnnamedParameter = {
from: Server,
type: Reliable,
call: ManyAsync,
data: (boolean, u32, string)
data: boolean
}

event TwoUnnamedParameters = {
from: Server,
type: Reliable,
call: ManyAsync,
data: (boolean, u32)
}`
</script>

Expand Down Expand Up @@ -65,6 +69,6 @@ Use synchronous events with extreme caution.
This field determines the data that is sent with the event. It can be any [Zap type](./types.md).

- If the event does not require any data, the `data` field should be excluded.
- You can pass multiple arguments to the event by separating each type with a comma and wrapping them all in parentheses:
- Parameter names and parentheses are optional to preserve backwards compatibility. If parantheses are excluded, the event can only have one unnamed parameter.

<CodeBlock :code="dataExample" />
31 changes: 21 additions & 10 deletions docs/config/functions.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
<script setup lang="ts">
const example = `funct Test = {
call: Async,
args: struct {
foo: u8,
bar: string
},
args: (Foo: u8, Bar: string),
rets: enum { Success, Fail }
}`

const multiArgsRetsExample = `funct MultipleArgsRets = {
const argsExample = `funct OneUnnamedParameter = {
call: Async,
args: (boolean, u8),
rets: (boolean, string)
args: u8,
rets: enum { Success, Fail }
}

funct TwoUnnamedParameters = {
call: Async,
args: (u8, string),
rets: enum { Success, Fail }
}
`

const multipleRets = `funct MultipleRets = {
call: Async,
args: boolean,
rets: (enum { Success, Fail }, string)
}`
</script>

Expand Down Expand Up @@ -48,15 +58,16 @@ Use synchronous functions with extreme caution.
This field determines the data that is sent to the server. It can be any [Zap type](./types.md).

- If the client doesn't send any data, the `args` field should be excluded.
- You can pass multiple arguments to the function by separating each type with a comma and wrapping them all in parentheses:
- Parameter names and parentheses are optional to preserve backwards compatibility. If parantheses are excluded, the function can only have one unnamed parameter.

<CodeBlock :code="multiArgsRetsExample" />
<CodeBlock :code="argsExample" />

### `rets`

This field determines the data that is sent back to the client from the server. It can be any [Zap type](./types.md).

- If the server doesn't return any data, the `rets` field should be excluded.
- Unlike `args`, `rets` cannot be named.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe we need a better error (sorry) then

error[2002]: expected ")", ",", "?", "["
  ┌─ net.zap:4:16
  │
4 │     rets: (test: enum { Success, Fail }, bar: string)
  │                ^ unexpected token

- The function can return multiple values by separating each type with a comma and wrapping them all in parentheses:

<CodeBlock :code="multiArgsRetsExample" />
<CodeBlock :code="multipleRets" />
14 changes: 4 additions & 10 deletions docs/intro/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,19 @@ event MyEvent = {
from: Server,
type: Reliable,
call: ManyAsync,
data: struct {
foo: u32,
bar: string,
},
data: (Foo: u32, Bar: string),
}`

const apiExample = `-- Server
local Zap = require(path.to.server.output)

Zap.MyEvent.FireAll({
foo = 123,
bar = "hello world",
})
Zap.MyEvent.FireAll(123, "hello world")

-- Client
local Zap = require(path.to.client.output)

Zap.MyEvent.On(function(data)
print(data.foo, data.bar)
Zap.MyEvent.On(function(Foo, Bar)
print(Foo, Bar)
end)`
</script>

Expand Down
10 changes: 5 additions & 5 deletions docs/usage/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ const configFile = `event MyEvent = {
from: Server,
type: Reliable,
call: ManyAsync,
data: struct {
data: (Options: struct {
foo: string,
bar: u8,
},
}),
}

event AnotherEvent = {
from: Client,
type: Reliable,
call: SingleAsync,
data: (boolean, u8)
data: (Foo: boolean, Bar: u8)
}`
</script>

Expand Down Expand Up @@ -48,7 +48,7 @@ If your event's [call field](../config/events.md#call) is `SingleAsync` or `Sing
local Zap = require(Path.To.Zap)

-- only server listeners are given the player argument
Zap.AnotherEvent.SetCallback(function(Player, Bool, Number)
Zap.AnotherEvent.SetCallback(function(Player, Foo, Bar)
-- Do something with the player and data
end)
```
Expand All @@ -58,7 +58,7 @@ If your event's [call field](../config/events.md#call) is `ManyAsync` or `ManySy
```lua
local Zap = require(Path.To.Zap)

local Disconnect = Zap.MyEvent.On(function(Data)
local Disconnect = Zap.MyEvent.On(function(Options)
-- Do something with the data
end)

Expand Down
10 changes: 8 additions & 2 deletions zap/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl std::fmt::Display for YieldType {
pub struct FnDecl<'src> {
pub name: &'src str,
pub call: FnCall,
pub args: Option<Vec<Ty<'src>>>,
pub args: Vec<Parameter<'src>>,
pub rets: Option<Vec<Ty<'src>>>,
pub id: usize,
}
Expand All @@ -93,10 +93,16 @@ pub struct EvDecl<'src> {
pub from: EvSource,
pub evty: EvType,
pub call: EvCall,
pub data: Option<Vec<Ty<'src>>>,
pub data: Vec<Parameter<'src>>,
pub id: usize,
}

#[derive(Debug, Clone)]
pub struct Parameter<'src> {
pub name: Option<&'src str>,
pub ty: Ty<'src>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum EvSource {
Server,
Expand Down
25 changes: 11 additions & 14 deletions zap/src/irgen/des.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,12 @@ impl Gen for Des {
self.buf.push(stmt);
}

fn gen(mut self, var: Var, types: &[Ty]) -> Vec<Stmt> {
for (i, ty) in types.iter().enumerate() {
let var = if i > 0 {
Var::Name(match &var {
Var::Name(name) => format!("{name}{}", i + 1),
_ => unreachable!(),
})
} else {
var.clone()
};

self.push_ty(ty, var);
fn gen<'a, I>(mut self, names: &[String], types: I) -> Vec<Stmt>
where
I: Iterator<Item = &'a Ty<'a>>,
{
for (ty, name) in types.zip(names) {
self.push_ty(ty, Var::Name(name.to_string()));
}

self.buf
Expand Down Expand Up @@ -431,11 +425,14 @@ impl Des {
}
}

pub fn gen(types: &[Ty], var: &str, checks: bool) -> Vec<Stmt> {
pub fn gen<'a, I>(types: I, names: &[String], checks: bool) -> Vec<Stmt>
where
I: IntoIterator<Item = &'a Ty<'a>>,
{
Des {
checks,
buf: vec![],
var_occurrences: HashMap::new(),
}
.gen(var.into(), types)
.gen(names, types.into_iter())
}
4 changes: 3 additions & 1 deletion zap/src/irgen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ pub mod ser;

pub trait Gen {
fn push_stmt(&mut self, stmt: Stmt);
fn gen(self, var: Var, types: &[Ty]) -> Vec<Stmt>;
fn gen<'a, I>(self, names: &[String], types: I) -> Vec<Stmt>
where
I: Iterator<Item = &'a Ty<'a>>;

fn push_local(&mut self, name: String, expr: Option<Expr>) {
self.push_stmt(Stmt::Local(name, expr))
Expand Down
25 changes: 11 additions & 14 deletions zap/src/irgen/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,12 @@ impl Gen for Ser {
self.buf.push(stmt);
}

fn gen(mut self, var: Var, types: &[Ty]) -> Vec<Stmt> {
for (i, ty) in types.iter().enumerate() {
let var = if i > 0 {
Var::Name(match &var {
Var::Name(name) => format!("{name}{}", i + 1),
_ => unreachable!(),
})
} else {
var.clone()
};

self.push_ty(ty, var);
fn gen<'a, I>(mut self, names: &[String], types: I) -> Vec<Stmt>
where
I: Iterator<Item = &'a Ty<'a>>,
{
for (ty, name) in types.zip(names) {
self.push_ty(ty, Var::Name(name.to_string()));
}

self.buf
Expand Down Expand Up @@ -369,11 +363,14 @@ impl Ser {
}
}

pub fn gen(types: &[Ty], var: &str, checks: bool) -> Vec<Stmt> {
pub fn gen<'a, I>(types: I, names: &[String], checks: bool) -> Vec<Stmt>
where
I: IntoIterator<Item = &'a Ty<'a>>,
{
Ser {
checks,
buf: vec![],
var_occurrences: HashMap::new(),
}
.gen(var.into(), types)
.gen(names, types.into_iter())
}
Loading
Loading