Skip to content

Commit

Permalink
Add functions, constants
Browse files Browse the repository at this point in the history
Signed-off-by: Christian Lindig <lindig@gmail.com>
  • Loading branch information
lindig committed Jun 16, 2024
1 parent e41566b commit 4f13d78
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
4 changes: 3 additions & 1 deletion bin/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ let main () =
match Tcalc.Parser.main Tcalc.Lexer.token lexbuf with
| Some seconds -> result seconds
| None -> ()
with _ -> Printf.printf "syntax error in \"%s\"\n%!" input
with
| Failure msg -> Printf.printf "syntax error in \"%s\": %s\n%!" input msg
| _ -> Printf.printf "syntax error in \"%s\"\n%!" input
in
repl "tcalc> " calc

Expand Down
27 changes: 25 additions & 2 deletions lib/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,28 @@ let fail fmt = Printf.ksprintf failwith fmt

let t = Hashtbl.create 10

let () = List.iter (fun (id, num) -> Hashtbl.replace t id num)
[ ("e", Float.exp 1.0)
; ("pi", Float.pi)
]

let add id num = Hashtbl.replace t id num

let lookup id = Hashtbl.find_opt t id |> function
| Some v -> v
| None -> fail "unknown value %s" id

let apply f args = match f, args with
| "log10", [x] -> Float.log10 x
| "log", [x] -> Float.log x
| "logn", [x; y] -> Float.log x /. Float.log y
| "sin", [x] -> Float.sin x
| "cos", [x] -> Float.cos x
| "tan", [x] -> Float.tan x
| "abs", [x] -> Float.abs x
| id, [] -> lookup id
| id, _ -> fail "function %s/%d is unknown" id (List.length args)

%}

%token <float> NUM
Expand All @@ -19,8 +36,9 @@ let lookup id = Hashtbl.find_opt t id |> function
%token EQUAL EOL
%left PLUS MINUS /* lowest precedence */
%left TIMES DIV /* medium precedence */
%nonassoc UMINUS /* highest precedence */
%right CARET
%left ID
%nonassoc LPAREN NUM UMINUS

%start main /* the entry point */
%type <float option> main
Expand All @@ -35,9 +53,14 @@ stmt:
ID EQUAL expr { add $1 $3; $3 }
;

app:
ID %prec ID { ($1, []) }
| app expr %prec ID { match $1 with (f, args) -> (f, $2 :: args) }
;

expr:
NUM { $1 }
| ID { lookup $1 }
| app %prec ID { match $1 with (f, args) -> apply f (List.rev args)}
| LPAREN expr RPAREN { $2 }
| expr PLUS expr { $1 +. $3 }
| expr MINUS expr { $1 -. $3 }
Expand Down
11 changes: 5 additions & 6 deletions tcalc.opam
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: "Minimal desktop calculator for timestamps"
description: """\
TCalc implements a minimal desktop calculator that in addition to
floating point numbers recognises durations in hh:min:sec format and
converts them to seconds. This can simplify time-based calculations."""
maintainer: "Christian Lindig <lindig@gmail.com>"
authors: "Christian Lindig <lindig@gmail.com>"
description:
"TCalc implements a minimal desktop calculator that in addition to floating point numbers recognises durations in hh:min:sec format and converts them to seconds. This can simplify time-based calculations."
maintainer: ["Christian Lindig <lindig@gmail.com>"]
authors: ["Christian Lindig <lindig@gmail.com>"]
license: "Unlicense"
homepage: "https://github.com/lindig/tcalc"
bug-reports: "https://github.com/lindig/tcalc/issues"
Expand Down

0 comments on commit 4f13d78

Please sign in to comment.