]>
git.kianting.info Git - clo/blob - src/index.ts
1 var fs
= require('fs');
2 import jsTokens from
"js-tokens";
3 import * as util from
'util';
10 * convert a `tkTree` AST to S-expr string
11 * @param t the `tkTree`
12 * @returns S-expr String
14 export function tkTreeToSExp(t
: tkTree
): string{
17 if (Array.isArray(t
)){
18 let strArray
= t
.map((x
)=>tkTreeToSExp(x
));
19 str
= "(" + strArray
.join(" ") + ")";
31 /**inspect the inner of the representation. */
32 let repr
= (x
: any)=>{return util
.inspect(x
, {depth
: null})};
39 * TokenPair for tokens' parser combinator
41 * matched: the matched (now and before) tokens
43 * remained: tokens to be matched
45 * ast: abstract syntax tree
47 export interface TokenPair
{
48 matched
: jsTokens
.Token
[]
49 remained
: jsTokens
.Token
[]
52 export type Some
<T
> = { _tag
: "Some"; value
: T
};
53 export type None
= { _tag
: "None" };
54 export type Maybe
<T
> = Some
<T
> | None
;
56 type Token
= jsTokens
.Token
;
57 type tkTree
= Token
| tkTree
[];
63 function toSome
<T
>(x
:T
): Maybe
<T
>{
64 return {_tag
: "Some", value
: x
};
68 * like `m ==> f` in ocaml
69 * @param m matchee wrapped
70 * @param f matching function
71 * @returns wrapped result
73 function thenDo(m
: Maybe
<TokenPair
>, f
: Function){
74 if (m
._tag
== "None"){
77 var a
: Maybe
<TokenPair
> = f(m
.value
);
78 if (a
._tag
== "Some"){
79 a
.value
.ast
= m
.value
.ast
.concat(a
.value
.ast
);
87 * @param m : the `TokenPair` to be consumed.
88 * @returns if the length of `m.remained` >= 1; consumes the matchee by 1 token
89 * and wraps it in `Some`,
90 * otherwise, returns `None`.
92 export function matchAny(m
: TokenPair
): Maybe
<TokenPair
> {
93 if (m
.remained
.length
>= 1) {
95 _tag
: "Some", value
: {
96 matched
: m
.matched
.concat(m
.remained
[0]),
97 remained
: m
.remained
.slice(1),
98 ast
: [m
.remained
[0]],
102 return { _tag
: "None" };
107 * like `f1 | f2` in regex
108 * @param f1 the first tried function
109 * @param f2 the second tried function
110 * @returns wrapped result
112 function orDo(f1
: Function, f2
: Function){
113 return (x
: TokenPair
) =>{
114 let res1
: Maybe
<TokenPair
> = f1(x
);
115 if (res1
._tag
== "Some"){
118 let res2
: Maybe
<TokenPair
> = f2(x
);
126 * @param f input token function. one token only.
127 * @returns combined finction
129 function notDo(f
: Function){
130 return (x
: TokenPair
) =>{
131 let res1
: Maybe
<TokenPair
> = f(x
);
132 if (res1
._tag
== "Some"){
133 return {_tag
:"None"};
135 let res2
= matchAny(x
);
141 function matchToken(typeName
: string, value
? : string):
142 (t
: TokenPair
) => Maybe
<TokenPair
>{
144 let headToken
= t
.remained
[0];
145 if (headToken
.type != typeName
){
146 return {_tag
:"None"};
148 if (value
=== undefined || value
== headToken
.value
){
150 matched
: t
.matched
.concat(headToken
),
151 remained
: t
.remained
.slice(1),
154 return {_tag
: "Some", value
: newTokenPair
};
156 return {_tag
:"None"};
167 const tokens
= Array.from(jsTokens(
168 `import foo from\t 'bar';
169 import * as util from 'util';
172 花非花,霧\\{非霧 。{{foo();}}下
175 console
.log("RESULT="+repr(tokens
));
178 var mainTokenPair
: TokenPair
= {
183 let a
= thenDo(thenDo(toSome(mainTokenPair
), matchToken('IdentifierName')),
184 notDo(matchToken('Punctuator', ';')));
187 console
.log("RESULT="+repr(a
));
188 if (a
._tag
== "Some"){
189 console
.log("SEXP="+tkTreeToSExp(a
.value
.ast
));