Skip to content

Instantly share code, notes, and snippets.

@Chubek
Created October 27, 2024 05:40
Show Gist options
  • Save Chubek/7221f9717aa92112fc50a758b76decc9 to your computer and use it in GitHub Desktop.
Save Chubek/7221f9717aa92112fc50a758b76decc9 to your computer and use it in GitHub Desktop.
The Guillmet Scheme

This is my progress, so far, in Guillmet scheme: a subset of Scheme language written in OCaml. It is meant to be compiled into x86-64 Assembly.

Why am I not making a proper repository? None of your bee's wax.

module Stream = struct
type 'a t = 'a Seq.t ref
exception Empty_stream
let empty = ref Seq.empty
let peek stm =
match !stm () with
| Seq.Nil -> raise Empty_stream
| Seq.Cons (hd, _) -> hd
let npeek stm n =
let rec aux acc stm' n' =
match !stm' () with
| Seq.Nil -> raise Empty_stream
| Seq.Cons (hd, tl) ->
if n = 0
then List.rev acc
else aux (hd :: acc) tl (n' - 1)
in
aux [] stm n
let next stm =
match !stm () with
| Seq.Nil -> raise Empty_stream
| Seq.Cons (hd, tl) -> stm := tl; hd
let take_while pred stm =
let rec aux acc stm' =
if pred (peek stm')
then aux (next stm' :: acc) stm'
else List.rev acc
in
aux [] stm
let take_until pred stm =
let rec aux acc stm' =
if pred (peek stm')
then List.rev acc
else peek (next stm' :: acc) stm'
in
aux [] stm
let discard_while pred stm =
let _ = take_while pred stm in
()
let discard_until pred stm =
let _ = take_until pred stm in
()
let map f stm = Seq.map f !stm
let iter f stm = Seq.iter f !stm
let filter p stm = Seq.filter p !stm
let of_list lst = ref (List.to_seq lst)
let of_array arr = ref (Array.to_seq arr)
let of_seq seq = ref seq
let append stm lst =
stm := !stm @ lst
let cons i stm =
stm := i :: !stm
let (<-) stm i = cons i stm
let (::) i stm = coms i stm
let (@) stm lst = append stm lst
end
module
module Scanner = struct
type t =
{ input : string
; file : in_channel
; tokstream : Token.t Stream.t
; charstream : char Stream.t
}
let skip_whitespace scn =
Stream.discard_while Lexeme.is_whitespace scn
let scan_integer scn =
let lst = Stream.take_while Lexeme.is_int_tail scn.charstream in
scn.tokstream <- Token.Integer (Int64.of_string (Lexeme.implode lst))
let scan_xinteger scn =
let lst = Stream.take_while Lexeme.is_xint_tail scn.charstream in
scn.tokstream <- Token.Integer (Int64.of_string "0x" ^ (Lexeme.implode lst))
let scan_ointeger scn =
let lst = Stream.take_while Lexeme.is_oint_tail scn.charstream in
scn.tokstream <- Token.Integer (Int64.of_string "0o" ^ (Lexeme.implode lst))
let scan_binteger scn =
let lst = Stream.take_while Lexeme.is_bint_tail scn.charstream in
scn.tokstream <- Token.Integer (Int64.of_string "0b" ^ (Lexeme.implode lst))
let scan_ident scn =
let lst = Stream.take_while Lexeme.is_ident_tail scn.charstream in
scn.tokstream <- Token.Ident (Lexeme.implode lst)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment