NOTE: Paw is under active development and is not ready for production use. See the roadmap to get an idea of where things are going. Also see known issues for a list of known problems that will eventually be fixed.
A cute little scripting language
Paw is a high-level, statically-typed, embeddable scripting language. It is designed to run on a virtual machine written in C.
- No dependencies
- Static strong typing
- Bidirectional type checking
- Block expressions
- Module system
- Exhaustive pattern matching and sum types
- Traits (interfaces checked at compile time)
- Generics and generic bounds
- Container literals (
[T]
and[K: V]
)
pub fn main() {
print("Hello, world!\n");
}
pub fn main() {
// Create a closure. The type of "n" is inferred as "int" and the
// return type as "str".
let fizzbuzz = |n| {
if n % 15 == 0 {
"FizzBuzz"
} else if n % 3 == 0 {
"Fizz"
} else if n % 5 == 0 {
"Buzz"
} else {
n.to_string()
}
};
// Call the closure for each integer 1 to 100, exclusive.
for i in range(1, 100, 1) {
print(fizzbuzz(i) + "\n");
}
}
pub enum Expr {
Zero,
Succ(Expr),
Add(Expr, Expr)
}
pub fn eval(e: Expr) -> int {
// match expressions must be exhaustive
match e {
Expr::Zero => 0,
Expr::Succ(x) => eval(x) + 1,
Expr::Add(x, y) => eval(x) + eval(y),
}
}
pub fn three() -> int {
let zero = Expr::Zero;
let one = Expr::Succ(zero);
let two = Expr::Add(one, one);
eval(Expr::Add(one, two))
}
struct Pair<X, Y> {
pub first: X,
pub second: Y,
}
type Vec2<Ty> = Pair<Ty, Ty>;
pub fn swap<Ty>(v: Vec2<Ty>) {
let temp = v.first;
v.first = v.second;
v.second = temp;
}
pub fn main() {
let v = Vec2{
first: 123,
second: 456,
};
swap(v);
print(v.first.to_string() + "\n"); // 456
print(v.second.to_string() + "\n"); // 123
}
pub trait Get<T> {
fn get(self) -> T;
}
struct Inner<X>: Get<X> {
pub value: X,
pub fn get(self) -> X {
self.value
}
}
struct Outer<X: Get<Y>, Y>: Get<Y> {
pub value: X,
pub fn get(self) -> Y {
self.value.get()
}
}
fn get<X: Get<Y>, Y>(x: X) -> Y {
x.get()
}
pub fn main() {
let inner = Inner{value: 123};
let outer = Outer{value: inner};
let value = get(outer);
print(value.to_string() + "\n"); // 123
}
Precedence | Operator | Description | Associativity |
---|---|---|---|
14 | () [] . ? |
Call, Subscript, Member access, Question mark | Left |
13 | ! - ~ # |
Not, Negate, Bitwise not, length | Right |
12 | as |
Cast | Left |
11 | * / % |
Multiply, Divide, Modulus | Left |
10 | + - |
Add, Subtract | Left |
9 | << >> |
Shift left, Shift right | Left |
8 | & |
Bitwise and | Left |
7 | ^ |
Bitwise xor | Left |
6 | | |
Bitwise or | Left |
5 | < <= > >= |
Relational comparisons | Left |
4 | == != |
Equality comparisons | Left |
3 | && |
And | Left |
2 | || |
Or | Left |
1 | = |
Assignment | Right |
- static, strong typing
- special syntax for builtin containers (
[T]
and[K: V]
) - type inference for polymorphic
fn
andstruct
- sum types/discriminated unions (
enum
) - product types (tuple)
- custom garbage collector (using Boehm GC for now)
- methods
- module system and
use
keyword - type inference for polymorphic
enum
- exhaustive pattern matching (
match
construct) - more featureful
use
declarations:use mod::*
,use mod::specific_symbol
,use mod as alias
, etc. - generic constraints/bounds
- constant folding, constant propagation
- traits (more like Swift protocols, maybe needs a different name)
- integrate traits into stdlib (iterators, hash map keys, etc.)
- error handling (
try
needs to be an operator, or we need something like a 'parameter pack' for generics to implement thetry
function) -
let
bindings/destructuring - function inlining
- refactor user-provided allocation interface to allow heap expansion
- Either need to support or report an error on generic bounds like
X: Trait<X>
- Causes a stack overflow due to infinite recursion
- Generic bounds should not be allowed on type aliases
- The C API has pretty much 0 type safety
- It may be necessary to reduce the scope of the C API somewhat
- Pointer tracking (test only) feature is broken on MSVC
- Might indicate a problem somewhere in the library
- Need a machine that can run Windows for debugging