Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed integer ranges when used in compound comprehensions. Improved p…

…erformance slightly of list comprehensions by not requiring a reverse of expressions.
  • Loading branch information...
commit 7f924e2589a332963adbe930deed3bd029676662 1 parent 70cd479
@massung authored
Showing with 17 additions and 10 deletions.
  1. +9 −2 README.md
  2. +2 −2 cell.ml
  3. +1 −1  compile.ml
  4. +3 −5 interp.ml
  5. +2 −0  test.fc
View
11 README.md
@@ -11,7 +11,6 @@ Ferret is an interpreted (bytecode compiled), functional scripting language impl
* Lexical scoping and block closures
* List comprehensions
* Prototype objects
-* Ranges
* Simple package system
Ferret was designed to be a language that was quick to throw something together in order to solve internet problems. For this reason, it has many features to assist with crypto, sockets, email, HTTP, FTP, parsing, etc.
@@ -43,5 +42,13 @@ Here's a quick, obligatory sample of what idiomatic Ferret looks like:
;; create a new dealer and ask for 5 hands of cards
let main () = let ch = dealer() in for _ in 1 to 5 do hand(ch)
-Functions in Ferret are just block closures. There is nothing special about them, aside from the fact that they are bound to a symbol.
+What is there to discern from this little bit of sample code?
+
+Every file is a `package`. This declaration must come first. It can be any valid identifier, but cannot replace an already existing package. All packages live in a flat namespace (there is no hierarchy of packages).
+
+Words are declared with the `let` keyword. If there are no formal parameters to the word, then it is evaluated at compile-time and is a constant. Otherwise it is a function. If you want to declare a function that takes no parameters, it should take a single formal: the unit value `()`.
+
+List comprehensions are done with the `for` keyword. Each word is bound to a range and the `do` form is evaluated for each iteration. Lists and strings are implicit ranges, while integer ranges can be created using the `to` or `downto` operators.
+
+ let
View
4 cell.ml
@@ -30,7 +30,7 @@ type t =
| Num of Fixnum.t
| Object of Atom.t list * t Atom.AtomMap.t
| Proc of proc
- | Range of t range
+ | Range of int range
| Ref of t ref
| String of string
| Tuple of t array
@@ -200,8 +200,8 @@ let proc_of_cell = function
(* get a ranged type from a cell *)
let range_of_cell = function
- | Range r -> r
| List xs -> new list_range xs
+ | Range r -> new range_t (Oo.copy r) (fun i -> Num (Int i))
| String s -> new range_t (new string_range s) (fun c -> Char c)
| x -> raise (Type_error x)
View
2  compile.ml
@@ -181,7 +181,7 @@ let for_loop locals cond terms n =
if (List.length locals) <> n
then raise Arity_mismatch
else
- let fs = List.fold_right (fun p acc -> local p >> acc) locals nop in
+ let fs = List.fold_left (fun acc p -> local p >> acc) nop locals in
let body =
match cond with
| Some test -> either test terms (literal Unit)
View
8 interp.ml
@@ -275,15 +275,13 @@ and make_inc_range st =
let limit = int_of_cell (Vector.pop st.stack) in
let from = int_of_cell (Vector.pop st.stack) in
let range = new Range.int_to_range from limit in
- let to_int i = Num (Fixnum.Int i) in
- Vector.push (Range (new Range.range_t range to_int)) st.stack
+ Vector.push (Range range) st.stack
and make_dec_range st =
let limit = int_of_cell (Vector.pop st.stack) in
let from = int_of_cell (Vector.pop st.stack) in
let range = new Range.int_downto_range from limit in
- let to_int i = Num (Fixnum.Int i) in
- Vector.push (Range (new Range.range_t range to_int)) st.stack
+ Vector.push (Range range) st.stack
(* create a reference cell *)
and mkref st = unary st (fun x -> Ref (ref x))
@@ -294,7 +292,7 @@ and deref st = unary st (fun ref -> !(ref_of_cell ref))
(* list comprehension *)
and do_for st n =
let f = proc_of_cell (Vector.pop st.stack) in
- let rs = List.rev (Vector.pop_list st.stack n) in
+ let rs = Vector.pop_list st.stack n in
(* perform a comprehension over each range *)
let rec comprehend ps = function
View
2  test.fc
@@ -58,3 +58,5 @@ let aux =
let z f = f*n+y in
z(5)
+;; using a created range
+let matrix = for x,y in 1 to 3,1 to 3 do (x*y)
Please sign in to comment.
Something went wrong with that request. Please try again.