-
Notifications
You must be signed in to change notification settings - Fork 0
/
hcA64.sml
121 lines (105 loc) · 4.82 KB
/
hcA64.sml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
(* Compiler. Calls the other structures*)
structure hcA64 =
struct
fun createLexerStream ( is : BasicIO.instream ) =
Lexing.createLexer ( fn buff => fn n => Nonstdio.buff_input is buff 0 n)
fun errorMess s = TextIO.output (TextIO.stdErr,s ^ "\n");
fun hcA64 filename back withIO =
let
val lexbuf = createLexerStream
(BasicIO.open_in (filename ^ ".hms"))
in
let
val pgm = HermesParser.Program HermesLexer.Token lexbuf
val _ = HermesTypes.check pgm
val reified = HermesReify.reifyProgram pgm
val partialled = HermesPE.pe reified back
val [(f, args, body, _)] = partialled (* nonexhaustive *)
val compiled = HermesCa64.compileProcedure f args body
val outString =
"#include <stdio.h>\n" ^
"#include <stdlib.h>\n" ^
"#include <inttypes.h>\n" ^
"#define __STDC_FORMAT_MACROS\n\n" ^
compiled ^
(if withIO then
"int countTokens(char line[])\n{\n" ^
" int count = 0, i = 0;\n\n" ^
" while (line[i] != '\\n' && line[i] != 0) {\n" ^
" while (line[i] == ' ') i++;\n" ^
" count++;\n" ^
" while (line[i] != ' ' && line[i] != '\\n' && line[i] != 0) i++;\n" ^
" }\n" ^
" return count;\n" ^
"}\n\n" ^
"\n\nint main() {\n" ^
" char *line, *c;\n" ^
" int i, err;\n" ^
HermesCx64.declareArgs args ^ "\n" ^
" line = (char *)malloc(2048);\n" ^
HermesCx64.readArgs args ^
" err = " ^ f ^ "(" ^ HermesCx64.callArgs args ^ ");\n\n" ^
" if (err)\n" ^
" printf(\"Assertion failed in line %d col. %d\\n\",\n" ^
" err/10000,err%10000);\n" ^
" else {\n" ^
HermesCx64.printArgs args ^
" \n}\n}\n"
else "")
in
TextIO.output (TextIO.stdOut, outString)
end
handle Parsing.yyexit ob => errorMess "Parser-exit\n"
| Parsing.ParseError ob =>
let
val (lin,col) = HermesLexer.getPos lexbuf
in
errorMess ("Parse-error at line "
^ makestring lin ^ ", column " ^ makestring col)
end
| HermesLexer.LexicalError (mess,(lin,col)) =>
errorMess ("Lexical error: " ^mess^ " at line "
^ makestring lin ^ ", column " ^ makestring col)
| HermesTypes.Error (mess, (lin,col)) =>
errorMess ("Type error: " ^mess^ " at line "
^ makestring lin ^ ", column " ^ makestring col)
| HermesPE.Error (mess, (lin,col)) =>
errorMess ("Specialisation error: " ^mess^ " at line "
^ makestring lin ^ ", column " ^ makestring col)
| BigInt.BigIntError (mess, (lin,col)) =>
errorMess ("Numeric error: " ^mess^ " at line "
^ makestring lin ^ ", column " ^ makestring col)
| HermesCx64.Error (mess, (lin,col)) =>
errorMess ("Compile error: " ^mess^ " at line "
^ makestring lin ^ ", column " ^ makestring col)
| a64.Error (mess) =>
errorMess ("a64 error: " ^ mess)
| SysErr (s,_) => errorMess ("Exception: " ^ s)
| Subscript => errorMess "subscript error"
end
val _ =
let val cmdLine = Mosml.argv () in
if List.length cmdLine = 2 (* no flags *)
then hcA64 (List.nth(cmdLine,1)) false true
else if List.length cmdLine = 3 andalso List.nth(cmdLine,1) = "-c"
then hcA64 (List.nth(cmdLine,2)) false false
else if List.length cmdLine = 3 andalso List.nth(cmdLine,2) = "-c"
then hcA64 (List.nth(cmdLine,1)) false false
else if List.length cmdLine = 3 andalso List.nth(cmdLine,1) = "-r"
then hcA64 (List.nth(cmdLine,2)) true true
else if List.length cmdLine = 3 andalso List.nth(cmdLine,2) = "-r"
then hcA64 (List.nth(cmdLine,1)) true true
else if List.length cmdLine = 3 andalso List.nth(cmdLine,1) = "-cr"
then hcA64 (List.nth(cmdLine,2)) true false
else if List.length cmdLine = 3 andalso List.nth(cmdLine,2) = "-cr"
then hcA64 (List.nth(cmdLine,1)) true false
else errorMess "call by, e.g., hcX64 TEA, hxX64 -c TEA, or hxX64 -r TEA"
end
(*
for each public (known) variable, input its value on one line.
for each secret (unknown) variable, input nothing (no input line)
for each public array, input its element values on one line,
separated by spaces.
for each secret array, input its size on one line.
*)
end