ocaml: add literal and layout stuff
This commit is contained in:
parent
9c52af5c27
commit
d7354de720
|
@ -1,4 +1,4 @@
|
|||
(executable
|
||||
(name yns)
|
||||
(modules yns)
|
||||
(libraries cmdliner))
|
||||
(libraries cmdliner yanais_core))
|
||||
|
|
|
@ -9,8 +9,10 @@
|
|||
(synopsis "The compiler for Yanais")
|
||||
(description "The compiler for Yanais")
|
||||
(depends
|
||||
(menhir (>= 20220210))
|
||||
(cmdliner (>= 1.1))
|
||||
(integers (>= 0.2))
|
||||
(menhir (>= 20220210))
|
||||
(uucp (>= 15.0))
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(library
|
||||
(name yanais_core)
|
||||
(public_name yanais.yanais_core)
|
||||
(synopsis "The compiler for Yanais"))
|
||||
(synopsis "The compiler for Yanais")
|
||||
(libraries integers uucp))
|
||||
|
||||
(documentation)
|
||||
|
|
38
ocaml/lib/layout.ml
Normal file
38
ocaml/lib/layout.ml
Normal file
|
@ -0,0 +1,38 @@
|
|||
type t = {
|
||||
size : int;
|
||||
(* alignment = 1 << align_exp *)
|
||||
align_exp : char;
|
||||
}
|
||||
|
||||
open Int
|
||||
|
||||
let alignment_of_exp x = shift_left 1 (Char.code x)
|
||||
|
||||
let alignment x = alignment_of_exp x.align_exp
|
||||
|
||||
let max_size_for_align_exp x =
|
||||
let y = alignment_of_exp x in
|
||||
let isz_max_sc = shift_right max_int 1 |> succ in
|
||||
isz_max_sc - y
|
||||
|
||||
(** appends a layout to this one, returns new layout and the offset **)
|
||||
let push orig next =
|
||||
let align_exp = max (Char.code orig.align_exp) (Char.code next.align_exp) |> Char.chr in
|
||||
|
||||
(* fill up ourselves so that the other element is correctly aligned *)
|
||||
let smask_sh = alignment next in
|
||||
let smask = pred smask_sh in
|
||||
let smasked = logand orig.size smask in
|
||||
|
||||
(* align size *)
|
||||
let size = if compare smasked zero == 0 then orig.size else (
|
||||
add (sub orig.size smasked) smask_sh
|
||||
) in
|
||||
|
||||
let offset = size in
|
||||
let size = size + next.size in
|
||||
if size <= max_size_for_align_exp align_exp
|
||||
then Option.some ({ size; align_exp; }, offset)
|
||||
else Option.none
|
||||
|
||||
let finish orig = push orig { size = 0; align_exp = orig.align_exp }
|
|
@ -1,2 +1,20 @@
|
|||
(* A lexer for yanais *)
|
||||
|
||||
type grp_state = Open | Close
|
||||
|
||||
type token =
|
||||
| Paren of grp_state
|
||||
| Brace of grp_state
|
||||
| LArr
|
||||
| RArr
|
||||
| LDubArr
|
||||
| RDubArr
|
||||
| Caret
|
||||
| Dot
|
||||
| DubColon
|
||||
| SemiColon
|
||||
| Assign
|
||||
| Ident of string
|
||||
| PatOut of string
|
||||
| DotIdent of string
|
||||
| Symbol
|
||||
|
|
63
ocaml/lib/lit.ml
Normal file
63
ocaml/lib/lit.ml
Normal file
|
@ -0,0 +1,63 @@
|
|||
type int_size = IPow of char | ISize
|
||||
|
||||
type ty_lit =
|
||||
| Type
|
||||
| Bool
|
||||
| Char
|
||||
| String
|
||||
| TIntSize
|
||||
| UnsInt of int_size
|
||||
| SigInt of int_size
|
||||
|
||||
type lit =
|
||||
| LTy of ty_lit
|
||||
| LIntSize of int_size
|
||||
| LNatural of int
|
||||
|
||||
let lty x = LTy x
|
||||
|
||||
let isz_of_str = function
|
||||
| "1" -> IPow '\000' |> Option.some
|
||||
| "2" -> IPow '\001' |> Option.some
|
||||
| "4" -> IPow '\002' |> Option.some
|
||||
| "8" -> IPow '\003' |> Option.some
|
||||
| "16" -> IPow '\004' |> Option.some
|
||||
| "32" -> IPow '\005' |> Option.some
|
||||
| "64" -> IPow '\006' |> Option.some
|
||||
| "128" -> IPow '\007' |> Option.some
|
||||
| "256" -> IPow '\008' |> Option.some
|
||||
| "_size" -> ISize |> Option.some
|
||||
| _ -> Option.none
|
||||
|
||||
let isz_to_str = function
|
||||
| IPow x -> Int.shift_left 1 (Char.code x) |> Int.to_string
|
||||
| ISize -> "_size"
|
||||
|
||||
let str_post loc s = String.sub s loc (String.length s - loc)
|
||||
|
||||
let of_str = function
|
||||
| "Type" -> LTy Type |> Option.some
|
||||
| "Bool" -> LTy Bool |> Option.some
|
||||
| "Char" -> LTy Char |> Option.some
|
||||
| "String" -> LTy String |> Option.some
|
||||
| "IntSize" -> LTy TIntSize |> Option.some
|
||||
|
||||
| s -> (if String.starts_with ~prefix:"ZI" s then
|
||||
str_post 2 s |> isz_of_str |> Option.map (fun x -> LIntSize x)
|
||||
else if String.starts_with ~prefix:"UI" s then
|
||||
str_post 2 s |> isz_of_str |> Option.map (fun x -> UnsInt x |> lty)
|
||||
else if String.starts_with ~prefix:"SI" s then
|
||||
str_post 2 s |> isz_of_str |> Option.map (fun x -> SigInt x |> lty)
|
||||
else if String.starts_with ~prefix:"-" s then Option.none
|
||||
else int_of_string_opt s |> Option.map (fun x -> LNatural x))
|
||||
|
||||
let to_str = function
|
||||
| LTy Type -> "Type"
|
||||
| LTy Bool -> "Bool"
|
||||
| LTy Char -> "Char"
|
||||
| LTy String -> "String"
|
||||
| LTy TIntSize -> "IntSize"
|
||||
| LIntSize sz -> "ZI" ^ (isz_to_str sz)
|
||||
| LTy (UnsInt sz) -> "UI" ^ (isz_to_str sz)
|
||||
| LTy (SigInt sz) -> "SI" ^ (isz_to_str sz)
|
||||
| LNatural n -> Int.to_string n
|
18
ocaml/lib/lit.mli
Normal file
18
ocaml/lib/lit.mli
Normal file
|
@ -0,0 +1,18 @@
|
|||
type int_size = IPow of char | ISize
|
||||
|
||||
type ty_lit =
|
||||
| Type
|
||||
| Bool
|
||||
| Char
|
||||
| String
|
||||
| TIntSize
|
||||
| UnsInt of int_size
|
||||
| SigInt of int_size
|
||||
|
||||
type lit =
|
||||
| LTy of ty_lit
|
||||
| LIntSize of int_size
|
||||
| LNatural of int
|
||||
|
||||
val of_str : string -> lit Option.t
|
||||
val to_str : lit -> string
|
Loading…
Reference in a new issue