mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-06 06:48:48 +00:00
Length, string -> std functions
This commit is contained in:
parent
216e716251
commit
f1430a1cdf
10 changed files with 21 additions and 39 deletions
|
|
@ -4,7 +4,7 @@ fun collect_ints_acc (v, tail) {
|
||||||
var i;
|
var i;
|
||||||
case v of
|
case v of
|
||||||
a@#val -> Cons (a, tail)
|
a@#val -> Cons (a, tail)
|
||||||
| #string -> tail
|
| #str -> tail
|
||||||
| _ ->
|
| _ ->
|
||||||
for i := 0, i < v.length, i := i + 1 do
|
for i := 0, i < v.length, i := i + 1 do
|
||||||
tail := collect_ints_acc (v[i], tail)
|
tail := collect_ints_acc (v[i], tail)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ F,system;
|
||||||
V,sysargs;
|
V,sysargs;
|
||||||
F,stringInt;
|
F,stringInt;
|
||||||
F,makeArray;
|
F,makeArray;
|
||||||
|
F,string;
|
||||||
|
F,length;
|
||||||
F,clone;
|
F,clone;
|
||||||
F,hash;
|
F,hash;
|
||||||
F,fst;
|
F,fst;
|
||||||
|
|
|
||||||
|
|
@ -335,7 +335,7 @@ int Ls__Infix_37 (void *p, void *q) {
|
||||||
return BOX(UNBOX(p) % UNBOX(q));
|
return BOX(UNBOX(p) % UNBOX(q));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int Blength (void *p) {
|
extern int Llength (void *p) {
|
||||||
data *a = (data*) BOX (NULL);
|
data *a = (data*) BOX (NULL);
|
||||||
|
|
||||||
ASSERT_BOXED(".length", p);
|
ASSERT_BOXED(".length", p);
|
||||||
|
|
@ -974,7 +974,7 @@ extern void* Lstringcat (void *p) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void* Bstringval (void *p) {
|
extern void* Lstring (void *p) {
|
||||||
void *s = (void *) BOX (NULL);
|
void *s = (void *) BOX (NULL);
|
||||||
|
|
||||||
__pre_gc () ;
|
__pre_gc () ;
|
||||||
|
|
|
||||||
|
|
@ -149,11 +149,11 @@ module Value =
|
||||||
module Builtin =
|
module Builtin =
|
||||||
struct
|
struct
|
||||||
|
|
||||||
let list = ["read"; "write"; ".elem"; ".length"; ".array"; ".stringval"]
|
let list = ["read"; "write"; ".elem"; "length"; ".array"; "string"]
|
||||||
let bindings () = List.map (fun name -> name, Value.Builtin name) list
|
let bindings () = List.map (fun name -> name, Value.Builtin name) list
|
||||||
let names = List.map (fun name -> name, FVal) list
|
let names = List.map (fun name -> name, FVal) list
|
||||||
|
|
||||||
let eval (st, i, o, vs) args = function
|
let eval (st, i, o, vs) args = function
|
||||||
| "read" -> (match i with z::i' -> (st, i', o, (Value.of_int z)::vs) | _ -> failwith "Unexpected end of input")
|
| "read" -> (match i with z::i' -> (st, i', o, (Value.of_int z)::vs) | _ -> failwith "Unexpected end of input")
|
||||||
| "write" -> (st, i, o @ [Value.to_int @@ List.hd args], Value.Empty :: vs)
|
| "write" -> (st, i, o @ [Value.to_int @@ List.hd args], Value.Empty :: vs)
|
||||||
| ".elem" -> let [b; j] = args in
|
| ".elem" -> let [b; j] = args in
|
||||||
|
|
@ -164,9 +164,9 @@ let eval (st, i, o, vs) args = function
|
||||||
| Value.Sexp (_, a) -> a.(i)
|
| Value.Sexp (_, a) -> a.(i)
|
||||||
) :: vs
|
) :: vs
|
||||||
)
|
)
|
||||||
| ".length" -> (st, i, o, (Value.of_int (match List.hd args with Value.Sexp (_, a) | Value.Array a -> Array.length a | Value.String s -> Bytes.length s))::vs)
|
| "length" -> (st, i, o, (Value.of_int (match List.hd args with Value.Sexp (_, a) | Value.Array a -> Array.length a | Value.String s -> Bytes.length s))::vs)
|
||||||
| ".array" -> (st, i, o, (Value.of_array @@ Array.of_list args)::vs)
|
| ".array" -> (st, i, o, (Value.of_array @@ Array.of_list args)::vs)
|
||||||
| ".stringval" -> let [a] = args in (st, i, o, (Value.of_string @@ Value.string_val a)::vs)
|
| "string" -> let [a] = args in (st, i, o, (Value.of_string @@ Value.string_val a)::vs)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -328,7 +328,7 @@ module Pattern =
|
||||||
| %"false" {Const 0}
|
| %"false" {Const 0}
|
||||||
| "#" %"box" {Boxed}
|
| "#" %"box" {Boxed}
|
||||||
| "#" %"val" {UnBoxed}
|
| "#" %"val" {UnBoxed}
|
||||||
| "#" %"string" {StringTag}
|
| "#" %"str" {StringTag}
|
||||||
| "#" %"sexp" {SexpTag}
|
| "#" %"sexp" {SexpTag}
|
||||||
| "#" %"array" {ArrayTag}
|
| "#" %"array" {ArrayTag}
|
||||||
| "#" %"fun" {ClosureTag}
|
| "#" %"fun" {ClosureTag}
|
||||||
|
|
@ -369,8 +369,6 @@ module Expr =
|
||||||
(* binary operator *) | Binop of string * t * t
|
(* binary operator *) | Binop of string * t * t
|
||||||
(* element extraction *) | Elem of t * t
|
(* element extraction *) | Elem of t * t
|
||||||
(* reference to an element *) | ElemRef of t * t
|
(* reference to an element *) | ElemRef of t * t
|
||||||
(* length *) | Length of t
|
|
||||||
(* string conversion *) | StringVal of t
|
|
||||||
(* function call *) | Call of t * t list
|
(* function call *) | Call of t * t list
|
||||||
(* assignment *) | Assign of t * t
|
(* assignment *) | Assign of t * t
|
||||||
(* composition *) | Seq of t * t
|
(* composition *) | Seq of t * t
|
||||||
|
|
@ -487,8 +485,6 @@ module Expr =
|
||||||
eval (st, i, o, (Value.of_int n) :: vs) Skip k
|
eval (st, i, o, (Value.of_int n) :: vs) Skip k
|
||||||
| String s ->
|
| String s ->
|
||||||
eval (st, i, o, (Value.of_string @@ Bytes.of_string s) :: vs) Skip k
|
eval (st, i, o, (Value.of_string @@ Bytes.of_string s) :: vs) Skip k
|
||||||
| StringVal s ->
|
|
||||||
eval conf k (schedule_list [s; Intrinsic (fun (st, i, o, s::vs) -> (st, i, o, (Value.of_string @@ Value.string_val s)::vs))])
|
|
||||||
| Var x ->
|
| Var x ->
|
||||||
let v =
|
let v =
|
||||||
match State.eval st x with
|
match State.eval st x with
|
||||||
|
|
@ -509,8 +505,6 @@ module Expr =
|
||||||
eval conf k (schedule_list [b; i; Intrinsic (fun (st, i, o, j::b::vs) -> Builtin.eval (st, i, o, vs) [b; j] ".elem")])
|
eval conf k (schedule_list [b; i; Intrinsic (fun (st, i, o, j::b::vs) -> Builtin.eval (st, i, o, vs) [b; j] ".elem")])
|
||||||
| ElemRef (b, i) ->
|
| ElemRef (b, i) ->
|
||||||
eval conf k (schedule_list [b; i; Intrinsic (fun (st, i, o, j::b::vs) -> (st, i, o, (Value.Elem (b, Value.to_int j))::vs))])
|
eval conf k (schedule_list [b; i; Intrinsic (fun (st, i, o, j::b::vs) -> (st, i, o, (Value.Elem (b, Value.to_int j))::vs))])
|
||||||
| Length e ->
|
|
||||||
eval conf k (schedule_list [e; Intrinsic (fun (st, i, o, v::vs) -> Builtin.eval (st, i, o, vs) [v] ".length")])
|
|
||||||
| Call (f, args) ->
|
| Call (f, args) ->
|
||||||
eval conf k (schedule_list (f :: args @ [Intrinsic (fun (st, i, o, vs) ->
|
eval conf k (schedule_list (f :: args @ [Intrinsic (fun (st, i, o, vs) ->
|
||||||
let es, vs' = take (List.length args + 1) vs in
|
let es, vs' = take (List.length args + 1) vs in
|
||||||
|
|
@ -656,8 +650,6 @@ module Expr =
|
||||||
primary[infix][atr]:
|
primary[infix][atr]:
|
||||||
s:(s:"-"? {match s with None -> fun x -> x | _ -> fun x -> Binop ("-", Const 0, x)})
|
s:(s:"-"? {match s with None -> fun x -> x | _ -> fun x -> Binop ("-", Const 0, x)})
|
||||||
b:base[infix][Val] is:( "." f:LIDENT args:(-"(" !(Util.list)[parse infix Val] -")")? {`Post (f, args)}
|
b:base[infix][Val] is:( "." f:LIDENT args:(-"(" !(Util.list)[parse infix Val] -")")? {`Post (f, args)}
|
||||||
| "." %"length" {`Len}
|
|
||||||
| "." %"string" {`Str}
|
|
||||||
| "[" i:parse[infix][Val] "]" {`Elem i}
|
| "[" i:parse[infix][Val] "]" {`Elem i}
|
||||||
| "(" args:!(Util.list0)[parse infix Val] ")" {`Call args}
|
| "(" args:!(Util.list0)[parse infix Val] ")" {`Call args}
|
||||||
)+
|
)+
|
||||||
|
|
@ -682,8 +674,6 @@ module Expr =
|
||||||
(fun b ->
|
(fun b ->
|
||||||
function
|
function
|
||||||
| `Elem i -> Elem (b, i)
|
| `Elem i -> Elem (b, i)
|
||||||
| `Len -> Length b
|
|
||||||
| `Str -> StringVal b
|
|
||||||
| `Post (f, args) -> Call (Var f, b :: match args with None -> [] | Some args -> args)
|
| `Post (f, args) -> Call (Var f, b :: match args with None -> [] | Some args -> args)
|
||||||
| `Call args -> (match b with Sexp _ -> invalid_arg "retry!" | _ -> Call (b, args))
|
| `Call args -> (match b with Sexp _ -> invalid_arg "retry!" | _ -> Call (b, args))
|
||||||
)
|
)
|
||||||
|
|
@ -693,8 +683,6 @@ module Expr =
|
||||||
let res = match lastElem, atr with
|
let res = match lastElem, atr with
|
||||||
| `Elem i , Reff -> ElemRef (b, i)
|
| `Elem i , Reff -> ElemRef (b, i)
|
||||||
| `Elem i , _ -> Elem (b, i)
|
| `Elem i , _ -> Elem (b, i)
|
||||||
| `Len , _ -> Length b
|
|
||||||
| `Str , _ -> StringVal b
|
|
||||||
| `Post (f, args), _ -> Call (Var f, b :: match args with None -> [] | Some args -> args)
|
| `Post (f, args), _ -> Call (Var f, b :: match args with None -> [] | Some args -> args)
|
||||||
| `Call args , _ -> (match b with Sexp _ -> invalid_arg "retry!" | _ -> Call (b, args))
|
| `Call args , _ -> (match b with Sexp _ -> invalid_arg "retry!" | _ -> Call (b, args))
|
||||||
in
|
in
|
||||||
|
|
@ -1266,10 +1254,8 @@ let run_parser cmd =
|
||||||
"while"; "do"; "od";
|
"while"; "do"; "od";
|
||||||
"for";
|
"for";
|
||||||
"fun"; "var"; "public"; "external"; "import";
|
"fun"; "var"; "public"; "external"; "import";
|
||||||
"length";
|
|
||||||
"string";
|
|
||||||
"case"; "of"; "esac"; "when";
|
"case"; "of"; "esac"; "when";
|
||||||
"box"; "val"; "string"; "sexp"; "array";
|
"box"; "val"; "str"; "sexp"; "array";
|
||||||
"infix"; "infixl"; "infixr"; "at"; "before"; "after";
|
"infix"; "infixl"; "infixr"; "at"; "before"; "after";
|
||||||
"true"; "false"; "lazy"; "eta"; "syntax"]
|
"true"; "false"; "lazy"; "eta"; "syntax"]
|
||||||
in
|
in
|
||||||
|
|
|
||||||
|
|
@ -830,12 +830,6 @@ let compile cmd ((imports, infixes), p) =
|
||||||
| Expr.Elem (a, i) -> let lelem, env = env#get_label in
|
| Expr.Elem (a, i) -> let lelem, env = env#get_label in
|
||||||
add_code (compile_list false lelem env [a; i]) lelem false [CALL (".elem", 2, tail)]
|
add_code (compile_list false lelem env [a; i]) lelem false [CALL (".elem", 2, tail)]
|
||||||
|
|
||||||
| Expr.Length e -> let llen, env = env#get_label in
|
|
||||||
add_code (compile_expr false llen env e) llen false [CALL (".length", 1, tail)]
|
|
||||||
|
|
||||||
| Expr.StringVal e -> let lsv, env = env#get_label in
|
|
||||||
add_code (compile_expr false lsv env e) lsv false [CALL (".stringval", 1, tail)]
|
|
||||||
|
|
||||||
| Expr.Assign (Expr.Ref x, e) -> let lassn, env = env#get_label in
|
| Expr.Assign (Expr.Ref x, e) -> let lassn, env = env#get_label in
|
||||||
let env , line = env#gen_line x in
|
let env , line = env#gen_line x in
|
||||||
let env , acc = env#lookup x in
|
let env , acc = env#lookup x in
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
let version = "Version 1.10, 5ae88f820, Sun Jan 31 21:07:17 2021 +0300"
|
let version = "Version 1.10, 216e71625, Sun Jan 31 22:25:31 2021 +0300"
|
||||||
|
|
|
||||||
|
|
@ -317,7 +317,7 @@ public fun lookupMemo (mm@[p, m], v) {
|
||||||
Some (w) -> w
|
Some (w) -> w
|
||||||
| None ->
|
| None ->
|
||||||
case v of
|
case v of
|
||||||
#string -> mm[1] := addMap (m, v, v); v
|
#str -> mm[1] := addMap (m, v, v); v
|
||||||
| _ ->
|
| _ ->
|
||||||
var vc = clone (v), i = case vc of #fun -> 1 | _ -> 0 esac;
|
var vc = clone (v), i = case vc of #fun -> 1 | _ -> 0 esac;
|
||||||
for skip, i < v.length, i := i + 1 do
|
for skip, i < v.length, i := i + 1 do
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ public fun logOn () {
|
||||||
|
|
||||||
public fun initOstap () {
|
public fun initOstap () {
|
||||||
tab := ref (emptyHashTab (1024, hash, compare));
|
tab := ref (emptyHashTab (1024, hash, compare));
|
||||||
restab := emptyCustomMemo (fun (x) {case x of #string -> true | _ -> false esac}, compare);
|
restab := emptyCustomMemo (fun (x) {case x of #str -> true | _ -> false esac}, compare);
|
||||||
hct := emptyMemo ()
|
hct := emptyMemo ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,7 +74,7 @@ public fun memo (f) {
|
||||||
|
|
||||||
public fun token (x) {
|
public fun token (x) {
|
||||||
case x of
|
case x of
|
||||||
#string -> memo $ fun (k) {fun (s) {k $ matchString (s, x)}}
|
#str -> memo $ fun (k) {fun (s) {k $ matchString (s, x)}}
|
||||||
| _ -> memo $ fun (k) {fun (s) {k $ matchRegexp (s, x)}}
|
| _ -> memo $ fun (k) {fun (s) {k $ matchRegexp (s, x)}}
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ var
|
||||||
lident = createRegexp ("[a-z][a-zA-Z_]*", "lowercase identifier"),
|
lident = createRegexp ("[a-z][a-zA-Z_]*", "lowercase identifier"),
|
||||||
uident = createRegexp ("[A-Z][a-zA-Z_]*", "uppercase identifier"),
|
uident = createRegexp ("[A-Z][a-zA-Z_]*", "uppercase identifier"),
|
||||||
ws = createRegexp ("\\([ \t\n]\\|--[^\n]*\n\\)*", "whitespace"),
|
ws = createRegexp ("\\([ \t\n]\\|--[^\n]*\n\\)*", "whitespace"),
|
||||||
str = createRegexp ("""\([^""]\|""""\)*""", "string literal"),
|
strlit = createRegexp ("""\([^""]\|""""\)*""", "string literal"),
|
||||||
decimal = createRegexp ("[0-9]+", "decimal literal"),
|
decimal = createRegexp ("[0-9]+", "decimal literal"),
|
||||||
chr = createRegexp ("'[^']'", "character literal");
|
chr = createRegexp ("'[^']'", "character literal");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ fun collect_ints_acc (v, tail) {
|
||||||
|
|
||||||
case v of
|
case v of
|
||||||
a@#val -> Cons (a, tail)
|
a@#val -> Cons (a, tail)
|
||||||
| #string -> tail
|
| #str -> tail
|
||||||
| _ ->
|
| _ ->
|
||||||
for i := 0, i < v.length, i := i + 1 do
|
for i := 0, i < v.length, i := i + 1 do
|
||||||
tail := collect_ints_acc (v[i], tail)
|
tail := collect_ints_acc (v[i], tail)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue