Skip to content

Commit

Permalink
Keep working on static typing
Browse files Browse the repository at this point in the history
Start working on classes
  • Loading branch information
andy-byers committed Jun 23, 2024
1 parent 2adda0c commit f0a7ca9
Show file tree
Hide file tree
Showing 36 changed files with 2,275 additions and 2,539 deletions.
21 changes: 7 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@ An unobtrusive scripting language

paw is a high-level, imperative, statically-typed programming language intended for embedding into larger projects.

## Goals
+ **Correctness**: This is the most-important goal, by far.
A language that returns incorrect results can't be very useful, so of course, paw should be implemented correctly.
The language should be designed for human readability, and eliminate syntax foot-guns where possible (for example, an `if` statement without '{}' followed by 2 indented lines will not guard the second line).
paw code should never invoke undefined behavior (UB), and the C interface should be carefully documented (since, of course, it is possible to have UB there).
+ **Performance**: paw should be (relatively) fast, possibly to the detriment of portability, but never at the expense of correctness.
Being dynamically-typed and hosted, paw will never achieve the same performance as C, the statically-typed host language.
This makes interoperating with C particularly important, since it is likely users will want to call C functions to perform computationally-intensive work.
+ **Ergonomics**: paw should be easy to use, and easy to learn.

## Syntax Overview

### Comments
Expand Down Expand Up @@ -46,21 +36,24 @@ global g: string = "hello, world!"
```

### Types
paw is statically-typed, meaning that all types must be known at compile time.
paw is statically-typed, meaning that types are bound to variables, not values.
The type of each variable must be known at compile time.
paw supports type inference on variable definitions.
The following example demonstrates creation of the basic value types.

```
// variables without an initializer (right-hand side) are set to `null`
// variables without an initializer (right-hand side) are set to the default
// value for the type given in the annotation
let b: bool
let i: int
// initializer is validated against the type annotation
let f: float = 10.0e-1
let a: [int] = [1, 2, 3]
let m: string[int] = {'a': 1, 'b': 2}
let f: fn(): int = fn(): int {return 42}
let f: (): int = fn(): int {return 42}
// supports type inference on variable definitions
// supports type inference
let b = false
let i = 40 + 2
let f = 1.0 * 2
Expand Down
34 changes: 9 additions & 25 deletions src/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,26 +108,21 @@ paw_Bool paw_is_truthy(paw_Env *P, int index)
// return pawV_truthy(*access(P, index));
}

paw_Bool paw_is_null(paw_Env *P, int index)
paw_Bool paw_is_bool(paw_Env *P, int index)
{
return paw_type(P, index) == PAW_NULL;
return paw_type(P, index) == PAW_TBOOL;
}

paw_Bool paw_is_boolean(paw_Env *P, int index)
paw_Bool paw_is_int(paw_Env *P, int index)
{
return paw_type(P, index) == PAW_TBOOL;
return paw_type(P, index) == PAW_TINT;
}

paw_Bool paw_is_float(paw_Env *P, int index)
{
return paw_type(P, index) == PAW_TFLOAT;
}

paw_Bool paw_is_int(paw_Env *P, int index)
{
return paw_type(P, index) == PAW_TINT;
}

paw_Bool paw_is_string(paw_Env *P, int index)
{
return paw_type(P, index) == PAW_TSTRING;
Expand All @@ -143,9 +138,9 @@ paw_Bool paw_is_array(paw_Env *P, int index)
return paw_type(P, index) == PAW_TARRAY;
}

paw_Bool paw_is_map(paw_Env *P, int index)
paw_Bool paw_is_tuple(paw_Env *P, int index)
{
return paw_type(P, index) == PAW_TMAP;
return paw_type(P, index) == PAW_TTUPLE;
}

paw_Bool paw_is_class(paw_Env *P, int index)
Expand All @@ -158,19 +153,6 @@ paw_Bool paw_is_foreign(paw_Env *P, int index)
return paw_type(P, index) == PAW_TFOREIGN;
}

paw_Bool paw_is_bigint(paw_Env *P, int index)
{
paw_assert(0); // TODO
// return !i_is_small(*access(P, index));
}

paw_Bool paw_is_number(paw_Env *P, int index)
{
paw_assert(0);
return 0;
// return pawV_is_number(*access(P, index));
}

int paw_type(paw_Env *P, int index)
{
const Value v = *access(P, index);
Expand Down Expand Up @@ -407,8 +389,10 @@ int paw_load(paw_Env *P, paw_Reader input, const char *name, void *ud)
};
const int status = pawC_try(P, parse_aux, &p);
pawM_free_vec(P, p.mem.scratch.data, p.mem.scratch.alloc);
pawM_free_vec(P, p.mem.scopes.data, p.mem.scopes.alloc);
pawM_free_vec(P, p.mem.st.scopes, p.mem.st.capacity); // TODO: free nested scope tables, symbols
pawM_free_vec(P, p.mem.ll.values, p.mem.ll.capacity);
pawM_free(P, p.mem.st.globals);
pawM_free(P, p.mem.st.toplevel);
return status;
}

Expand Down
6 changes: 2 additions & 4 deletions src/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
static inline const char *api_typename(int type)
{
switch (type) {
case PAW_NULL:
return "null";
case PAW_TUNIT:
return "unit";
case PAW_TBOOL:
return "boolean";
case PAW_TINT:
Expand All @@ -21,8 +21,6 @@ static inline const char *api_typename(int type)
return "string";
case PAW_TARRAY:
return "array";
case PAW_TMAP:
return "map";
case PAW_TFUNCTION:
return "function";
case PAW_TCLASS:
Expand Down
4 changes: 2 additions & 2 deletions src/auxlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ static void add_nstring(paw_Env *P, Buffer *buf, const char *str, size_t len, in
memcpy(ptr, str, len);
}

void pawL_add_value(paw_Env *P, Buffer *buf, TypeTag tag)
void pawL_add_value(paw_Env *P, Buffer *buf, paw_Type type)
{
size_t len; // value must be on top of the stack
const char *str = pawV_to_string(P, P->top.p[-1], t_type(tag), &len);
const char *str = pawV_to_string(P, P->top.p[-1], type, &len);
if (str == NULL) {
// add the type name and address
str = paw_push_fstring(P, "%s (%p)", paw_typename(P, -1), paw_pointer(P, -1));
Expand Down
2 changes: 1 addition & 1 deletion src/auxlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void pawL_add_nstring(paw_Env *P, Buffer *buf, const char *s, size_t n);
void pawL_add_integer(paw_Env *P, Buffer *buf, paw_Int i);
void pawL_add_float(paw_Env *P, Buffer *buf, paw_Float f);
void pawL_add_pointer(paw_Env *P, Buffer *buf, void *p);
void pawL_add_value(paw_Env *P, Buffer *print, TypeTag tag);
void pawL_add_value(paw_Env *P, Buffer *print, paw_Type type);
void pawL_add_vfstring(paw_Env *P, Buffer *buf, const char *fmt, va_list arg);
void pawL_add_fstring(paw_Env *P, Buffer *buf, const char *fmt, ...);

Expand Down
14 changes: 7 additions & 7 deletions src/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,10 @@ static void call_return(paw_Env *P, StackPtr base, paw_Bool has_return)
Value ret = P->top.p[-1];
P->top.p = base + 1;
P->top.p[-1] = ret;
} else {
P->top.p = base;
} else {
// implicit 'return ()'
P->top.p = base + 1;
P->top.p->u = 0; // clear value
}
P->cf = P->cf->prev;
}
Expand All @@ -175,12 +177,10 @@ static void handle_ccall(paw_Env *P, StackPtr base, Native *ccall)
static void check_fixed_args(paw_Env *P, Proto *f, int argc)
{
if (argc < f->argc) {
paw_assert(0);
// pawR_error(P, PAW_ERUNTIME, "not enough arguments (expected %s%d)",
// f->is_va ? "at least " : "", f->argc);
pawR_error(P, PAW_ERUNTIME, "not enough arguments (expected %s%d)",
f->is_va ? "at least " : "", f->argc);
} else if (!f->is_va && argc > f->argc) {
paw_assert(0);
// pawR_error(P, PAW_ERUNTIME, "too many arguments (expected %d)", f->argc);
pawR_error(P, PAW_ERUNTIME, "too many arguments (expected %d)", f->argc);
}
}

Expand Down
9 changes: 8 additions & 1 deletion src/call.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static inline Value *pawC_pushv(paw_Env *P, Value v)
static inline Value *pawC_push0(paw_Env *P)
{
StackPtr sp = pawC_stkinc(P, 1);
v_set_null(sp);
v_set_0(sp);
return sp;
}

Expand All @@ -91,6 +91,13 @@ static inline Value *pawC_pushb(paw_Env *P, paw_Bool b)
return sp;
}

static inline Value *pawC_pusho(paw_Env *P, Object *o)
{
StackPtr sp = pawC_stkinc(P, 1);
v_set_object(sp, o);
return sp;
}

Value *pawC_pushns(paw_Env *P, const char *s, size_t n);
Value *pawC_pushs(paw_Env *P, const char *s);

Expand Down
Loading

0 comments on commit f0a7ca9

Please sign in to comment.