mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-06 06:48:48 +00:00
Added tutorial
This commit is contained in:
parent
b7271d167a
commit
b0e5bc26e3
10 changed files with 153 additions and 6 deletions
|
|
@ -72,7 +72,8 @@ Multiple postfixes are allowed, for example
|
||||||
|
|
||||||
The basic form of expression is \nonterm{primary}. The simplest form of primary is an identifier or constant. Keywords \lstinline|true| and \lstinline|false|
|
The basic form of expression is \nonterm{primary}. The simplest form of primary is an identifier or constant. Keywords \lstinline|true| and \lstinline|false|
|
||||||
designate integer constants 1 and 0 respectively, character constant is implicitly converted into its ASCII code. String constants designate arrays
|
designate integer constants 1 and 0 respectively, character constant is implicitly converted into its ASCII code. String constants designate arrays
|
||||||
of one-byte characters. Infix constants allow to reference a functional value associated with corresponding infix operator, and functional constant (\emph{lambda-expression})
|
of one-byte characters. Infix constants allow to reference a functional value associated with corresponding infix operator (however, a value associated with
|
||||||
|
builtin assognment operator "\lstinline|:=|" can not be taken), and functional constant (\emph{lambda-expression})
|
||||||
designates an anonymous functional value in the form of closure.
|
designates an anonymous functional value in the form of closure.
|
||||||
|
|
||||||
\begin{figure}[h]
|
\begin{figure}[h]
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ redefinition of builtin infix operators:
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item redefinitions of builtin infix operators can not be exported;
|
\item redefinitions of builtin infix operators can not be exported;
|
||||||
\item the assignment operator "\lstinline|:=|" can not be redefined.
|
\item the assignment operator "\lstinline|:=|" can not be redefined;
|
||||||
|
\item infix definitions can not be mutually recursive.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
The syntax for infix operator definition is shown on Fig.~\ref{custom_infix_construct}; a custom infix definition must specify exactly two arguments.
|
The syntax for infix operator definition is shown on Fig.~\ref{custom_infix_construct}; a custom infix definition must specify exactly two arguments.
|
||||||
|
|
|
||||||
BIN
lalgol.png
BIN
lalgol.png
Binary file not shown.
|
Before Width: | Height: | Size: 636 B |
|
|
@ -382,11 +382,18 @@ static void printStringBuf (char *fmt, ...) {
|
||||||
vprintStringBuf (fmt, args);
|
vprintStringBuf (fmt, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int is_valid_heap_pointer (void *p);
|
||||||
|
|
||||||
static void printValue (void *p) {
|
static void printValue (void *p) {
|
||||||
data *a = (data*) BOX(NULL);
|
data *a = (data*) BOX(NULL);
|
||||||
int i = BOX(0);
|
int i = BOX(0);
|
||||||
if (UNBOXED(p)) printStringBuf ("%d", UNBOX(p));
|
if (UNBOXED(p)) printStringBuf ("%d", UNBOX(p));
|
||||||
else {
|
else {
|
||||||
|
if (! is_valid_heap_pointer(p)) {
|
||||||
|
printStringBuf ("0x%x", p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
a = TO_DATA(p);
|
a = TO_DATA(p);
|
||||||
|
|
||||||
switch (TAG(a->tag)) {
|
switch (TAG(a->tag)) {
|
||||||
|
|
@ -398,7 +405,7 @@ static void printValue (void *p) {
|
||||||
printStringBuf ("<closure ");
|
printStringBuf ("<closure ");
|
||||||
for (i = 0; i < LEN(a->tag); i++) {
|
for (i = 0; i < LEN(a->tag); i++) {
|
||||||
if (i) printValue ((void*)((int*) a->contents)[i]);
|
if (i) printValue ((void*)((int*) a->contents)[i]);
|
||||||
else printStringBuf ("%x", (void*)((int*) a->contents)[i]);
|
else printStringBuf ("0x%x", (void*)((int*) a->contents)[i]);
|
||||||
|
|
||||||
if (i != LEN(a->tag) - 1) printStringBuf (", ");
|
if (i != LEN(a->tag) - 1) printStringBuf (", ");
|
||||||
}
|
}
|
||||||
|
|
@ -453,7 +460,7 @@ static void printValue (void *p) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printStringBuf ("*** invalid tag: %x ***", TAG(a->tag));
|
printStringBuf ("*** invalid tag: 0x%x ***", TAG(a->tag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -494,7 +501,7 @@ static void stringcat (void *p) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printStringBuf ("*** invalid tag: %x ***", TAG(a->tag));
|
printStringBuf ("*** invalid tag: 0x%x ***", TAG(a->tag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1437,6 +1444,10 @@ static void gc_swap_spaces (void) {
|
||||||
# define IS_FORWARD_PTR(p) \
|
# define IS_FORWARD_PTR(p) \
|
||||||
(!UNBOXED(p) && IN_PASSIVE_SPACE(p))
|
(!UNBOXED(p) && IN_PASSIVE_SPACE(p))
|
||||||
|
|
||||||
|
int is_valid_heap_pointer (void *p) {
|
||||||
|
return IS_VALID_HEAP_POINTER(p);
|
||||||
|
}
|
||||||
|
|
||||||
extern size_t * gc_copy (size_t *obj);
|
extern size_t * gc_copy (size_t *obj);
|
||||||
|
|
||||||
static void copy_elements (size_t *where, size_t *from, int len) {
|
static void copy_elements (size_t *where, size_t *from, int len) {
|
||||||
|
|
|
||||||
15
tutorial/Expressions.lama
Normal file
15
tutorial/Expressions.lama
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
printf ("if, case, for, while, repeat etc. are all expressions.\n");
|
||||||
|
|
||||||
|
printf ("Case-expression: %s\n", case A (1, 2, 3) of A (x, y, z) -> z esac.string);
|
||||||
|
|
||||||
|
printf ("If-expression: %s\n", if true then 2 else 3 fi +
|
||||||
|
if false then 6 else 7 fi.string);
|
||||||
|
|
||||||
|
printf ("Scope-expression: %s\n", {local i, s = 0;
|
||||||
|
for i := 0, i < 10, i := i + 1 do
|
||||||
|
s := s + i
|
||||||
|
od;
|
||||||
|
s
|
||||||
|
}.string
|
||||||
|
)
|
||||||
|
|
||||||
7
tutorial/Functions.lama
Normal file
7
tutorial/Functions.lama
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import Fun;
|
||||||
|
import List;
|
||||||
|
|
||||||
|
printf ("Functions are first-class, higher-order.\n");
|
||||||
|
|
||||||
|
printf ("Factorial: %d\n", fix (fun (f) {fun (n) {if n == 1 then 1 else n * f (n-1) fi}})(5));
|
||||||
|
printf ("Function composition: %d\n", foldl (infix #, id, map (fun (i) {fun (x) {x+i}}, {1, 2, 3})) $ 10)
|
||||||
12
tutorial/Hello.lama
Normal file
12
tutorial/Hello.lama
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
printf ("Hi, this is Lama...\n");
|
||||||
|
printf ("I can construct values of various shapes,\n");
|
||||||
|
printf ("convert them into strings and print. Here you are:\n");
|
||||||
|
|
||||||
|
printf ("Regular integers: %d or even %s\n", 3, 3.string);
|
||||||
|
printf ("Lists: %s\n", {1, 2, 3}.string);
|
||||||
|
printf ("Arrays/tuples: %s\n", [1, 2, 3].string);
|
||||||
|
printf ("S-expressions: %s\n", Man ("Jonh", "Smith").string);
|
||||||
|
printf ("Functions: %s\n", fun (x, y) {x+y}.string);
|
||||||
|
printf ("These structures can be nested and heterogeneous: %s\n", {[1, "2"], Apple, fun (x) {Melon (3)}}.string);
|
||||||
|
|
||||||
|
printf ("That's all for now, bye!\n")
|
||||||
13
tutorial/Makefile
Normal file
13
tutorial/Makefile
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
FILES=$(wildcard *.lama)
|
||||||
|
ALL=$(sort $(FILES:.lama=))
|
||||||
|
LAMAC=../src/lamac
|
||||||
|
|
||||||
|
all: $(ALL)
|
||||||
|
|
||||||
|
%: %.lama
|
||||||
|
$(LAMAC) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -Rf *.s *.o *.i *~
|
||||||
54
tutorial/PatternMatching.lama
Normal file
54
tutorial/PatternMatching.lama
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
fun show (x) {
|
||||||
|
fun show (level, x) {
|
||||||
|
for local i; i := 0, i<level, i := i + 1 do
|
||||||
|
printf (" ")
|
||||||
|
od;
|
||||||
|
|
||||||
|
case x of
|
||||||
|
#unboxed -> printf ("integer %d\n", x);
|
||||||
|
return
|
||||||
|
| #array -> printf ("array\n")
|
||||||
|
| #string -> printf ("string\n")
|
||||||
|
| #sexp -> printf ("S-expression\n")
|
||||||
|
| #fun -> printf ("closure 0x%x\n", x[0])
|
||||||
|
esac;
|
||||||
|
|
||||||
|
for local i; i := case x of #fun -> 1 | _ -> 0 esac, i < x.length, i := i + 1 do
|
||||||
|
show (level + 2, x[i])
|
||||||
|
od
|
||||||
|
}
|
||||||
|
|
||||||
|
show (0, x)
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("Pattern matching is a better way to deal with the structure of a value:\n");
|
||||||
|
show (3);
|
||||||
|
show ([3]);
|
||||||
|
show ({1, 2});
|
||||||
|
show (["abc", [1, fun (x) {x+1}], {3, 4}]);
|
||||||
|
|
||||||
|
printf ("But the main designation of pattern matching is to deal with S-expressions.\n");
|
||||||
|
printf ("You can discriminate the scrutinee on the tag:\n");
|
||||||
|
|
||||||
|
case E of
|
||||||
|
A -> printf ("Nope.\n")
|
||||||
|
| B -> printf ("Nope.\n")
|
||||||
|
| C -> printf ("Nope.\n")
|
||||||
|
| D -> printf ("Nope.\n")
|
||||||
|
| E -> printf ("Yes, this is E.\n")
|
||||||
|
esac;
|
||||||
|
|
||||||
|
printf ("You can discriminate the scrutinee on the number of arguments as well:\n");
|
||||||
|
|
||||||
|
case A of
|
||||||
|
A (_) -> printf ("Nope.\n")
|
||||||
|
| A (_, _) -> printf ("Nope.\n")
|
||||||
|
| A -> printf ("This is A with no subvalues.\n")
|
||||||
|
| A (_, _, _) -> printf ("Nope.\n")
|
||||||
|
esac;
|
||||||
|
|
||||||
|
printf ("You may also use composite patterns:\n");
|
||||||
|
|
||||||
|
case A (["x", "y", "z"], {1, 2, 3}) of
|
||||||
|
A (a@[_, _, z], _ : tl) -> printf ("a=%s, z=%s, tl=%s\n", a.string, z.string, tl.string)
|
||||||
|
esac
|
||||||
33
tutorial/Values.lama
Normal file
33
tutorial/Values.lama
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
local samples = [
|
||||||
|
{"a", "b", "c"},
|
||||||
|
"string",
|
||||||
|
[],
|
||||||
|
Fruit ("apple"),
|
||||||
|
fun (){skip}
|
||||||
|
];
|
||||||
|
|
||||||
|
fun show () {
|
||||||
|
-- Note: it would be much better to use iterArray from standard unit Array;
|
||||||
|
-- in that case, however, we wouldn't be able to showcase
|
||||||
|
-- for-loops and []-expressions.
|
||||||
|
for local i; i := 0, i < samples.length, i := i+1 do
|
||||||
|
printf (" %s has %d subvalue(s):\n", samples[i].string, samples[i].length);
|
||||||
|
for local j; j := 0, j < samples[i].length, j := j+1 do
|
||||||
|
printf (" subvalue [%d] = %s\n", j, samples[i][j].string)
|
||||||
|
od
|
||||||
|
od
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("And now we look at accessing/modifying/analyzing the values.\n");
|
||||||
|
printf ("Any composite value can be asked on the number of its immediate subvalues,\n");
|
||||||
|
printf ("and these subvalues can be accessed:\n");
|
||||||
|
|
||||||
|
show ();
|
||||||
|
|
||||||
|
printf ("And the subvalues of a composite value can be reassigned.\n");
|
||||||
|
|
||||||
|
samples [2] := [1, 2, 3];
|
||||||
|
samples [0][1] := {};
|
||||||
|
|
||||||
|
show ()
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue