Skip to content
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
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,41 @@ Save this as `main.wave`, then run it directly:
wavec run main.wave
```

## Modules and Vex packages

Wave keeps each imported file in its own module namespace. A bare import names
a Vex dependency, a qualified package path names a source module, and `./`
explicitly names a file relative to the importing module:

```wave
import("add");
import("add::math");
import("./helpers" as helpers);
import("add")::{sum, Point};

fun main() {
var qualified = add::sum(1, 2);
var selected = sum(1, 2);
var local = helpers::triple(3);
var point = Point();
}
```

A dependency named `add` resolves to its canonical `src/lib.wave` entry;
`add::math` resolves to `src/math.wave`. Only declarations marked `pub` can be
selected or accessed through another module:

```wave
fun internal_sum(a: i32, b: i32) -> i32 { return a + b; }
pub fun sum(a: i32, b: i32) -> i32 { return internal_sum(a, b); }
pub struct Point {}
```

`pub` controls Wave module visibility and is independent from `export(c)`,
which controls the C ABI boundary. `main` is always a private entry point, so
`pub fun main()` is rejected. A module can deliberately forward public API with
`pub import("module")::{symbol};`.

## Install

Linux and macOS:
Expand Down
92 changes: 87 additions & 5 deletions examples/doom.wave
Original file line number Diff line number Diff line change
@@ -1,8 +1,90 @@
import("std::sys::linux::fs");
import("std::sys::linux::tty");
import("std::time::clock");
import("std::time::sleep");
import("std::math::trig");
import("std::sys::linux::fs")::{
FS_O_RDONLY,
FS_O_WRONLY,
FS_O_RDWR,
FS_O_CREAT,
FS_O_EXCL,
FS_O_TRUNC,
FS_O_APPEND,
FS_O_NONBLOCK,
FS_F_OK,
FS_X_OK,
FS_W_OK,
FS_R_OK,
FS_SEEK_SET,
FS_SEEK_CUR,
FS_SEEK_END,
FS_F_GETFL,
FS_F_SETFL,
open,
close,
dup,
dup2,
pipe,
fsync,
fcntl,
read,
write,
getcwd,
chdir,
access,
lseek,
unlink,
mkdir,
rmdir,
Stat,
stat,
fstat,
};
import("std::sys::linux::tty")::{
TTY_SYS_IOCTL,
TTY_SYS_FCNTL,
TTY_TCGETS,
TTY_TCSETS,
TTY_TCSETSW,
TTY_TCSETSF,
TTY_TCSANOW,
TTY_TCSADRAIN,
TTY_TCSAFLUSH,
TTY_F_GETFL,
TTY_F_SETFL,
TTY_O_NONBLOCK,
TTY_ICANON,
TTY_ECHO,
TTY_VTIME_IDX,
TTY_VMIN_IDX,
Termios,
TtyRawState,
tty_getattr,
tty_setattr,
tty_getfl,
tty_setfl,
tty_enable_raw_nonblock,
tty_restore,
};
import("std::time::clock")::{
time_now_realtime,
time_now_monotonic,
time_now_realtime_ns,
time_now_monotonic_ns,
TimeSpec,
nanosleep,
clock_gettime,
};
import("std::time::sleep")::{
time_sleep_ns,
time_sleep_us,
time_sleep_ms,
};
import("std::math::trig")::{
MATH_PI_F64,
MATH_TWO_PI_F64,
abs_f64,
wrap_angle_pi_f64,
sin_f64,
cos_f64,
sqrt_f64,
};

const STDIN_FILENO: i32 = 0;
const STDOUT_FILENO: i32 = 1;
Expand Down
219 changes: 200 additions & 19 deletions examples/observability_gateway.wave
Original file line number Diff line number Diff line change
@@ -1,22 +1,203 @@
import("std::env::cwd");
import("std::env::environ");
import("std::path::copy");
import("std::string::len");
import("std::string::trim");
import("std::string::ascii");
import("std::string::hash");
import("std::math::int");
import("std::math::bits");
import("std::math::float");
import("std::math::num");
import("std::time::clock");
import("std::time::diff");
import("std::time::sleep");
import("std::buffer::alloc");
import("std::buffer::write");
import("std::buffer::read");
import("std::mem::ops");
import("std::net::tcp");
import("std::env::cwd")::{
env_getcwd,
env_chdir,
env_access,
};
import("std::env::environ")::{
EnvResult,
env_result_ok,
env_result_err,
env_unwrap_or,
env_get,
env_exists,
env_get_i64,
env_get_i32,
env_get_i32_default,
env_get_i64_default,
};
import("std::path::copy")::{
path_join2,
path_basename_copy,
path_dirname_copy,
};
import("std::path::analyze")::{
path_ext_start,
path_has_ext,
};
import("std::path::core")::{
path_is_abs,
};
import("std::string::len")::{
len,
is_empty,
};
import("std::string::trim")::{
trim_left_index,
trim_right_index,
trim_range,
};
import("std::string::ascii")::{
is_digit,
is_lower,
is_upper,
is_alpha,
is_alnum,
is_space,
to_lower,
to_upper,
};
import("std::string::hash")::{
djb2_32,
fnv1a_64,
};
import("std::math::int")::{
num_abs,
num_min,
num_max,
num_clamp,
ptr_swap,
abs,
min,
max,
clamp,
sign,
is_even,
is_odd,
div_ceil_pos,
div_floor_pos,
swap_i32,
};
import("std::math::bits")::{
is_pow2,
align_down,
align_up,
low_bit,
popcount,
ctz32,
bit_length,
ilog2_floor,
ilog2_ceil,
is_pow2_i64,
align_down_i64,
align_up_i64,
low_bit_i64,
popcount64,
ctz64,
bit_length64,
ilog2_floor64,
ilog2_ceil64,
bswap32,
bswap64,
};
import("std::math::float")::{
abs_f32,
min_f32,
max_f32,
clamp_f32,
};
import("std::math::num")::{
gcd,
lcm,
pow_i32,
};
import("std::time::clock")::{
time_now_realtime,
time_now_monotonic,
time_now_realtime_ns,
time_now_monotonic_ns,
TimeSpec,
nanosleep,
clock_gettime,
};
import("std::time::diff")::{
time_diff_ns,
time_diff_ms,
};
import("std::time::sleep")::{
time_sleep_ns,
time_sleep_us,
time_sleep_ms,
};
import("std::buffer::alloc")::{
buffer_new,
buffer_new_default,
buffer_free,
buffer_clear,
buffer_reserve,
tbuffer_new,
tbuffer_free,
tbuffer_clear,
tbuffer_reserve,
Buffer,
TypedBuffer,
};
import("std::buffer::write")::{
buffer_push,
buffer_append,
buffer_append_str,
buffer_set,
tbuffer_push,
tbuffer_set,
};
import("std::buffer::read")::{
buffer_at,
tbuffer_ptr,
tbuffer_len,
tbuffer_at,
};
import("std::mem::ops")::{
mem_set,
mem_zero,
mem_copy,
mem_move,
mem_cmp,
mem_eq,
mem_find_byte,
mem_swap,
mem_copy_items,
mem_set_items,
mem_move_items,
mem_zero_items,
mem_copy_checked,
mem_move_checked,
mem_set_checked,
mem_zero_checked,
};
import("std::net::tcp")::{
TcpAddr,
TcpListener,
TcpStream,
_tcp_to_net_addr,
_tcp_from_net_addr,
htons,
htonl,
tcp_addr,
tcp_addr_any,
tcp_addr_loopback,
tcp_set_reuseaddr,
tcp_bind,
tcp_bind_with_backlog,
tcp_bind_addr,
tcp_accept,
tcp_accept_addr,
tcp_close_listener,
tcp_connect,
tcp_try_connect,
tcp_read,
tcp_write,
tcp_write_all,
tcp_read_exact,
tcp_write_str,
tcp_stream_set_nonblock,
tcp_stream_get_nonblock,
tcp_listener_set_nonblock,
tcp_listener_get_nonblock,
tcp_from_fd,
tcp_listener_from_fd,
tcp_stream_valid,
tcp_listener_valid,
tcp_close,
};

const DEFAULT_PORT: i32 = 18080;
const ALERT_THRESHOLD: i32 = 3;
Expand Down
5 changes: 5 additions & 0 deletions front/lexer/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ impl<'a> Lexer<'a> {
lexeme: "export".to_string(),
line: self.line,
},
"pub" => Token {
token_type: TokenType::Pub,
lexeme: "pub".to_string(),
line: self.line,
},
"type" => Token {
token_type: TokenType::Type,
lexeme: "type".to_string(),
Expand Down
9 changes: 8 additions & 1 deletion front/lexer/src/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,18 @@ impl<'a> Lexer<'a> {
})
}
':' => {
if self.match_next(':') {
return Ok(Token {
token_type: TokenType::DoubleColon,
lexeme: "::".to_string(),
line: self.line,
});
}
return Ok(Token {
token_type: TokenType::Colon,
lexeme: ":".to_string(),
line: self.line,
})
});
}
'<' => {
if self.match_next('<') {
Expand Down
Loading
Loading