Created
April 8, 2011 01:39
-
-
Save papersail/909140 to your computer and use it in GitHub Desktop.
mfcalc (translated from Ocaml to F#)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
module Lexer | |
open System | |
open Parser | |
open Microsoft.FSharp.Text.Lexing | |
let lexeme = LexBuffer<_>.LexemeString | |
let func_table = [ | |
"sin", sin; | |
"cos", cos; | |
"tan", tan; | |
"asin", asin; | |
"acos", acos; | |
"atan", atan; | |
"log", log; | |
"exp", exp; | |
"sqrt", sqrt; | |
] | |
let functions = Map.ofList func_table | |
let ident lexbuf tokenText = | |
if Map.containsKey tokenText functions then | |
let f = Map.find tokenText functions | |
FNCT f | |
else | |
VAR tokenText | |
} | |
let digit = ['0'-'9']+ | |
let alpha = ['a'-'z' 'A'-'Z'] | |
let ident = alpha+ (alpha | digit)* | |
let floatNum = digit ('.' digit)? | |
let newline = '\n' | |
rule token = parse | |
| [' ' '\t'] { token lexbuf } | |
| floatNum { NUM (Double.Parse(lexeme lexbuf)) } | |
| newline { NEWLINE } | |
| '+' { PLUS } | |
| '-' { MINUS } | |
| '*' { MULTIPLY } | |
| '/' { DIVIDE } | |
| '^' { CARET } | |
| '(' { LPAREN } | |
| ')' { RPAREN } | |
| '=' { EQ} | |
| ident { ident lexbuf (lexeme lexbuf) } | |
| _ { token lexbuf } | |
| eof { EOF } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System | |
open Parser | |
open Lexer | |
let main () = | |
let lexbuf = Lexing.LexBuffer<_>.FromTextReader Console.In | |
while not lexbuf.IsPastEndOfStream do | |
Parser.input Lexer.token lexbuf | |
main () |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%{ | |
open System | |
let var_table = Map.empty | |
%} | |
%token LPAREN RPAREN EQ | |
%token <float> NUM | |
%token PLUS MINUS MULTIPLY DIVIDE CARET | |
%token <string> VAR | |
%token <float->float> FNCT | |
%token NEWLINE EOF | |
%left PLUST MINUS | |
%left MULTIPLY DIVIDE | |
%left NEG | |
%right CARET | |
%start input | |
%type <unit> input | |
%% | |
input: { } | |
| input line { } | |
line: NEWLINE {} | |
| exp NEWLINE { printf "\t%.10g\n" $1 | |
Console.Out.Flush() } | |
exp: NUM { $1 } | |
| VAR { if Map.containsKey $1 var_table then | |
Map.find $1 var_table | |
else | |
0.0 | |
} | |
| VAR EQ exp { Map.add $1 $3 var_table |> ignore; $3 } | |
| FNCT LPAREN exp RPAREN { $1 $3 } | |
| exp PLUS exp { $1 + $3 } | |
| exp MINUS exp { $1 - $3 } | |
| exp MULTIPLY exp { $1 * $3 } | |
| exp DIVIDE exp { $1 / $3 } | |
| exp CARET exp { $1 ** $3 } | |
| MINUS exp %prec NEG { - $2 } | |
| LPAREN exp RPAREN { $2 } | |
%% |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment