]> git.kianting.info Git - clo/blob - src/index.ts
48d2c866b1d5f622a965eb212194f267bb18722a
[clo] / src / index.ts
1 var fs = require('fs');
2 import { argv, resourceUsage } from 'node:process';
3 import * as tk from './tokenize.js';
4 import * as util from 'util';
5 import { reduceRotation } from 'pdf-lib';
6
7 /**
8 * token tree type.
9 */
10 type tkTree = tkTree[] | tk.Token
11
12 export interface TokenMatcheePair {
13 matched: tkTree[]
14 remained: tk.Token[]
15 }
16
17 export interface MaybeTokensAST{
18 maybeTokens: tk.Maybe<TokenMatcheePair>;
19 ast: tkTree;
20 }
21
22 /**
23 * @description
24 * match one token type.
25 *
26 * it returns a function which test if the type of first token of the `remained` part of
27 * the argument of the function is `typ` , if it's true, update the `TokenMatcheePair` wrapped
28 * in `Some`. Otherwise, it returns `None`.
29 * * @param typ : the type to be test.
30 * @returns the updated `TokenMatcheePair` wrapped in `Some(x)` or `None`.
31 */
32 export function m1TType(typ: tk.TokenType):
33 (m: TokenMatcheePair) => tk.Maybe<TokenMatcheePair> {
34 return (m: TokenMatcheePair) => {
35 if (m.remained.length == 0) {
36 return { _tag: "None" };
37 }
38 /**
39 * token to be matched
40 * */
41 const ttbm = m.remained[0];
42
43 if (ttbm.type == typ) {
44 let new_matched = m.matched.concat(ttbm);
45 let result : tk.Some<TokenMatcheePair> = {
46 _tag: "Some", value: {
47 matched: new_matched,
48 remained: m.remained.slice(1)
49 }
50 };
51 return result;
52 }
53 else {
54 return { _tag: "None" };
55 }
56 }
57 };
58
59 let toSome = tk.toSome;
60 let thenDo = tk.thenDo;
61 let zeroOrOnceDo = tk.zeroOrOnceDo;
62 let orDo = tk.orDo;
63 let zeroOrMoreDo = tk.zeroOrMoreDo;
64
65
66 argv.forEach((val, index) => {
67 console.log(`${index}=${val}`);
68 });
69
70 let commandInput = "int a str b"//argv[2];
71 let commandInputTokenized = tk.tokenize(commandInput);
72 let commandInputTokenizedFiltered = commandInputTokenized.filter(
73 (x : tk.Token)=>{return x.type != tk.TokenType.SP &&
74 x.type != tk.TokenType.NL});
75 console.log("aaa: "+util.inspect(commandInputTokenizedFiltered, { showHidden: true, depth: null }));
76
77 /**
78 * matchee pair of commandInputTokenized
79 */
80 let commandTPair : TokenMatcheePair = {matched:[],
81 remained: commandInputTokenizedFiltered};
82
83
84 let tInt = m1TType(tk.TokenType.INT);
85 let tFlo = m1TType(tk.TokenType.FLO);
86 let tStr = m1TType(tk.TokenType.STR);
87 let tId = m1TType(tk.TokenType.ID);
88 let tApos = m1TType(tk.TokenType.APOS);
89
90
91 function tBool (x : TokenMatcheePair) :tk.Maybe<TokenMatcheePair> {
92 let text = x.remained[0].text
93 if (text == "true" || text == "false"){
94 return thenDo(toSome(x), m1TType(tk.TokenType.ID));
95 }else{
96 return {_tag : "None"};
97 }
98 }
99
100 /**
101 * define the right hand side of a grammar
102 * eg. `LHS ::= a + b`
103 * @param process the right hand side processing : eg. `a + b` in `LHS`
104 * @param arrange define the order (0 starting) of the elements of the result.
105 * ast. : eg. `a + c` is `1 0 2` `(+ a c)`
106 * @returns the processed ast.
107 */
108 function gramRHS (process: Function, arrange : number[]){
109 return (m : TokenMatcheePair)=>{
110
111 let middle : tk.Maybe<TokenMatcheePair> = process(m);
112
113 console.log("Middle"+util.inspect(middle, { showHidden: true, depth: null }));
114
115 if (middle._tag == "None"){
116 return middle;
117 }
118 else{
119 let matched = middle.value.matched;
120 let arrLength = arrange.length;
121 let returnRrray : tkTree[] = Array(arrange.length);
122
123 arrange.forEach((val, index) => {
124 returnRrray[arrange[index]] = matched[index];
125 });
126
127 let matchedTmp1Length = matched.length-arrLength;
128 console.log(matchedTmp1Length);
129 var matchedTmp1 : tkTree[] = matched
130 .slice(0,matchedTmp1Length);
131
132 console.log("matchedTmp1"+util.inspect(matchedTmp1, { showHidden: true, depth: null }));
133 console.log("returnRrray"+util.inspect(returnRrray, { showHidden: true, depth: null }));
134 matchedTmp1.push(returnRrray);
135
136
137 let result : tk.Some<TokenMatcheePair> = {_tag:"Some",
138 value : {matched : matchedTmp1,
139 remained : middle.value.remained}};
140 return result;
141 }
142 }
143 }
144
145 /**
146 * typeABS ::= "'" ID
147 */
148 var typeABS = (x : TokenMatcheePair)=>
149 {
150 var result = thenDo(thenDo(toSome(x),tApos),tId);
151 if (result._tag == "Some" && "text" in result.value.matched[1]){
152 var realToken : tk.Token = result.value.matched[1];
153 realToken.text = "'"+realToken.text;
154 result.value.matched = [realToken];
155 }
156 return result;
157 }
158
159 /**
160 * TypeId ::= typeABS | ID
161 */
162 var typeName = (x : TokenMatcheePair)=>
163 {
164 return thenDo(toSome(x), orDo(typeABS, tId));
165 }
166
167 /**
168 * CONST ::= INT | STR | FLO | BOOL
169 */
170
171 /**
172 * TODO: 要用 debugger 檢查分析問題
173 */
174 var constParser = gramRHS((x : TokenMatcheePair)=>
175 {return thenDo(toSome(x),orDo(orDo(orDo(tInt,tFlo),tStr),tBool))}, [0]);
176
177 /**
178 * storing the tree
179 */
180 var astTree : tkTree = [];
181
182 /**
183 * TYPE_PAIR ::= TYP_ID ID
184 */
185 var typePair = (x : MaybeTokensAST)=>
186 {
187
188
189 let a = thenDo(thenDo(x.maybeTokens, typeName), tId);
190 if (a._tag == "Some"){
191 let matched = a.value.matched;
192 let slice = matched.slice(matched.length-2);
193 console.log("slice"+slice);
194
195 let b : MaybeTokensAST = {maybeTokens : a, ast : slice};
196 return b;
197 }
198 else{
199 let b : MaybeTokensAST= {maybeTokens : a, ast : []};
200 return b;
201 }
202 }
203
204 /**
205 * function's arguments
206 * FN_ARGS = TYPE_PAIR ("," TYPE_PAIR)+
207 */
208
209 var fnArgs = (x : TokenMatcheePair)=>
210 {
211 let wrapper : MaybeTokensAST = {maybeTokens : toSome(x), ast : []};
212 let a = typePair(wrapper);
213 console.log("AAAAA"+util.inspect(a, { showHidden: true, depth: null }));
214 let abanibi = typePair(a);
215 console.log("ABNB"+util.inspect(abanibi, { showHidden: true, depth: null }));
216
217
218 return {maybeTokens : abanibi.maybeTokens, ast : [a.ast, abanibi.ast]};
219
220 };
221
222 let tree = fnArgs(commandTPair);
223 console.log("CHRANN"+util.inspect(tree, { showHidden: true, depth: null }));