]> git.kianting.info Git - clo/blob - src/index.ts
20230910 : add basic parser `CONST` rule, and add the grammar rule.
[clo] / src / index.ts
1 var fs = require('fs');
2 import { argv } from 'node:process';
3 import * as tk from './tokenize.js';
4 import * as util from 'util';
5
6 /**
7 * token tree type.
8 */
9 type tkTree = tk.Token[] | tk.Token
10
11 export interface TokenMatcheePair {
12 matched: tkTree[]
13 remained: tk.Token[]
14 }
15
16 /**
17 * @description
18 * match one token type.
19 *
20 * it returns a function which test if the type of first token of the `remained` part of
21 * the argument of the function is `typ` , if it's true, update the `TokenMatcheePair` wrapped
22 * in `Some`. Otherwise, it returns `None`.
23 * * @param typ : the type to be test.
24 * @returns the updated `TokenMatcheePair` wrapped in `Some(x)` or `None`.
25 */
26 export function m1TType(typ: tk.TokenType):
27 (m: TokenMatcheePair) => tk.Maybe<TokenMatcheePair> {
28 return (m: TokenMatcheePair) => {
29 if (m.remained.length == 0) {
30 return { _tag: "None" };
31 }
32 /**
33 * token to be matched
34 * */
35 const ttbm = m.remained[0];
36
37 if (ttbm.type == typ) {
38 m.matched.push(ttbm);
39 return {
40 _tag: "Some", value: {
41 matched: m.matched,
42 remained: m.remained.slice(1)
43 }
44 };
45 }
46 else {
47 return { _tag: "None" };
48 }
49 }
50 };
51
52 let toSome = tk.toSome;
53 let thenDo = tk.thenDo;
54 let orDo = tk.orDo;
55
56
57 argv.forEach((val, index) => {
58 console.log(`${index}=${val}`);
59 });
60
61 let commandInput = argv[2];
62 let commandInputTokenized = tk.tokenize(commandInput);
63 console.log(commandInputTokenized);
64
65 /**
66 * matchee pair of commandInputTokenized
67 */
68 let commandTPair : TokenMatcheePair = {matched:[],
69 remained: commandInputTokenized};
70
71
72 let tInt = m1TType(tk.TokenType.INT);
73 let tFlo = m1TType(tk.TokenType.FLO);
74 let tStr = m1TType(tk.TokenType.STR);
75 function tBool (x : TokenMatcheePair) :tk.Maybe<TokenMatcheePair> {
76 let text = x.remained[0].text
77 if (text == "true" || text == "false"){
78 return thenDo(toSome(x), m1TType(tk.TokenType.ID));
79 }else{
80 return {_tag : "None"};
81 }
82 }
83
84 /**
85 * define the right hand side of a grammar
86 * eg. `LHS ::= a + b`
87 * @param process the right hand side processing : eg. `a + b` in `LHS`
88 * @param arrange define the order (0 starting) of the elements of the result.
89 * ast. : eg. `a + c` is `1 0 2` `(+ a c)`
90 * @returns the processed ast.
91 */
92 function gramRHS (process: Function, arrange : number[]){
93 return (m : TokenMatcheePair)=>{
94
95 let result : tk.Maybe<TokenMatcheePair> = process(m);
96 console.log(`result ${result}`)
97 if (result._tag == "None"){
98 return result;
99 }
100 else{
101 let matched = result.value.matched;
102 let return_array : tkTree[] = Array(arrange.length);
103
104 arrange.forEach((val, index) => {
105 return_array[arrange[index]] = matched[index];
106 });
107
108 return return_array;
109 }
110 }
111 }
112
113 /**
114 * CONST ::= INT | STR | FLO | BOOL
115 */
116 var constParser = gramRHS((x : TokenMatcheePair)=>
117 {return thenDo(toSome(x),orDo(orDo(orDo(tInt,tFlo),tStr),tBool))}, [0]);
118
119 let tree = constParser(commandTPair);
120 console.log(util.inspect(tree, { showHidden: true, depth: null }));