gdritter repos pico-ml-old / c7bf7f8
initial commit Getty Ritter 8 years ago
6 changed file(s) with 146 addition(s) and 0 deletion(s). Collapse all Expand all
1 # PicoML
2
3 A minimal statically-typed functional programming language. Not actually
4 an ML. Written entirely in cross-platform C; allows for multiple code
5 generators.
6
7 Exhaustive feature list:
8
9 - sums (eager)
10 - products (lazy)
11 - functions
12 - currying
13 - closures
14 - references
15 - implicit values (searched by type, must be unambiguous)
16 - libc bindings (incl. malloc)
17
18 Maybe looking like
19
20 ~~~~
21 data List a =
22 [ Cons a (List a)
23 , Nil
24 ]
25
26 map (f : a -> b) (l : List a) : List b =
27 case l of
28 Cons x xs -> Cons (f x) (map f xs)
29 Nil -> Nil
30
31 record Stream a =
32 { .head a
33 , .tail (Stream a)
34 }
35
36 mapS (f : a -> b) (s : Stream a) : Stream b =
37 { .head = f s.head
38 , .tail = mapS f s.tail
39 }
40
41 record Functor f = { .fmap ((a -> b) -> f a -> f b) }
42
43 implicit listFunctor : Functor List = { .fmap = map }
44 implicit streamFunctor : Functor Stream = { .fmap = mapS }
45 ~~~~
1 #include "ast.h"
2 #include <stdlib.h>
3 #include <string.h>
4
5 char*
6 str_of_slice(slice_t slice)
7 {
8 char* str = malloc(slice.len + 1);
9 if (!str) return 0;
10 strncpy(str, slice.start, slice.len);
11 str[slice.len] = '\0';
12 return str;
13 }
1 struct slice {
2 char *start;
3 size_t len;
4 size_t indentation;
5 } slice_t;
6
7 typedef slice_t ident_t;
8
9 struct decl {
10 ident_t name;
11 type_t *type;
12 expr_t *expr;
13 } decl_t;
14
15 struct expr {
16 enum {
17 EXPR_APP,
18 EXPR_LAM,
19 EXPR_LET,
20 EXPR_VAR,
21 EXPR_LIT
22 } tag;
23 } expr_t;
24
25 char* str_of_slice(slice_t);
26
27 /* expr constructors */
28 expr_t* mk_app(expr_t*, expr_t*);
29 expr_t* mk_lam(ident_t*, expr_t*);
30 expr_t* mk_let(ident_t*, expr_t*, expr_t*);
31 expr_t* mk_var(ident_t*);
32 expr_t* mk_annot(expr_t*, type_t*);
33 expr_t* mk_lit_int(ident_t*);
34 expr_t* mk_lit_float(ident_t*);
35 expr_t* mk_lit_char(ident_t*);
36 expr_t* mk_lit_str(ident_t*);
1 enum token {
2 TOK_LIDENT,
3 TOK_UIDENT,
4 TOK_STRING,
5 TOK_CHAR,
6 TOK_INT,
7
8 TOK_LPAR,
9 TOK_RPAR,
10 TOK_LBRAC,
11 TOK_RBRAC,
12 TOK_LCURL,
13 TOK_RCURL,
14 TOK_ARROW,
15 TOK_IDENT,
16 };
1 -- this is just a normal type definition
2 record Monoid m =
3 { .mempty m
4 , .mappend (m -> m -> m)
5 }
6
7 implicit monoidIntAdd : Monoid Int =
8 { .mempty = 0
9 , .mappend = (+)
10 }
11
12 monoidIntMul : Monoid Int =
13 { .mempty = 1
14 , .mappend = (*)
15 }
16
17 mconcat (implicit m : Monoid m) (lst : List m) : m =
18 case lst of
19 Cons x xs -> m.mappend x xs
20 Nil -> m.mempty
21
22 main = print (mconcat monoidIntAdd [1,2,3])
23 ; print (mconcat monoidIntMul [1,2,3])
24 ; print (mconcat [1,2,3])
1 record Add x =
2 { .zero x
3 , .add (x -> x -> x)
4 }
5
6 record Mul x =
7 { .one x
8 , .mul (x -> x -> x)
9 }
10
11 sum (implicit add : Add a) = foldl add.zero add.add
12 prod (implicit mul : Mul a) = foldl mul.one mul.mul