ocaml: add literal and layout stuff

This commit is contained in:
Alain Zscheile 2024-02-09 22:19:55 +01:00
parent 9c52af5c27
commit d7354de720
7 changed files with 143 additions and 3 deletions

View file

@ -1,4 +1,4 @@
(executable
(name yns)
(modules yns)
(libraries cmdliner))
(libraries cmdliner yanais_core))

View file

@ -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))
)
)

View file

@ -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
View 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 }

View file

@ -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
View 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
View 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