From: Tan Kian-ting Date: Wed, 14 Feb 2024 14:24:53 +0000 (+0800) Subject: fix some basic funciton of parser - rebuild X-Git-Url: https://git.kianting.info/?a=commitdiff_plain;h=950c4e04233e9e2d158976c05416cbcbf62af605;p=anotherTypesetter fix some basic funciton of parser - rebuild --- diff --git a/docs/defineASTandGrammar.md b/docs/defineASTandGrammar.md index a641bc9..71ac11f 100644 --- a/docs/defineASTandGrammar.md +++ b/docs/defineASTandGrammar.md @@ -44,7 +44,7 @@ C語言、Python語言就算有許多的關鍵字、操作符、符號或是常 ## 決定語法 那我們要如何制定這個語言的語法,這樣我們才能夠寫出符合這個語法的函數,然後再用tokenizer和parser轉成AST樹。 -不考慮` + - * /`這種運算子,以及向量的表示子,函數可以用`ID(arg1, arg2, ...)`這種方式來表示,其中`arg_x`是引數,`ID`是識別子(identifier,可以把它想成變函數的名字)。 +函數可以用`ID arg1 arg2`這種方式來表示,其中`arg_x`是引數,`ID`是識別子(identifier,可以把它想成變函數的名字)。 變數可以是`ID`,`arg_n`可以是`ID`或常數(量)。 @@ -56,56 +56,48 @@ C語言、Python語言就算有許多的關鍵字、操作符、符號或是常 - 字串:`'"' (不是「"」的任一字元|('\' '"')) '"'`(`.`表示任何一個字元) -然而我們還是需要綁定變數`let x = var in boby`(在`body`裡面,`x`指代`var`)、`set x = var`(改變變數值)、lambda`lambda (x)=>{body}`。另外為了要區別要在PDF印上去的一般字元,在這個檔案的常數、變數、函數、關鍵字等前後需要加@表示(但是函數、lambda裡面的變數不用)。比如`@foo(a, b)@`、`@lambda(x)@`、`@"IAmAString"@`、`@2.2@`、`@3@`(後三者應該很少用到)可是若需在PDF印`@`時怎辦?那就用`\@`。比如`foo\@example.com`。 +然而我們還是需要綁定變數`let int x = var in body`(在`body`裡面,`x`指代`var`)、改變變數值)、lambda`fn (int x) (int y) -> + x y`(採用前綴表示法,`+`在前)。另外為了要區別要在PDF印上去的一般字元,在這個檔案的常數、變數、函數、關鍵字等前後需要加@表示(但是函數、lambda裡面的變數不用)。比如`@foo a b@`、`@let int x = 3 in toString (+ x 2)@`、`@"IAmAString"@`、`@2.2@`、`@3@`(後三者應該很少用到)可是若需在PDF印`@`時怎辦?那就用`\@`。比如`foo\@example.com`。 所以我們可以定義以下的BNF風文法: ``` -Language ::= MainTxt | Exprs | Comment - -Comment ::= '/*' (不含'*/'的任何字元組合)* '*/' - - -MainTxt ::= (('\' '@')| 非@非空白字元)+ //顯示的文字。「我是一隻貓」或是「www\@example.com」 - -// Exprs 表示一群定義變數、常數、函數、函數套用的表達式 -Exprs ::= @ Expr* @ // *表示前面的重複0次以上(包含不出現) - -// Comment also included -// "(" and ")" only for applying function -Expr ::= (Letting | Setting | Lambda | | Var| Const) | "(" Applying ")" | Comment - -Letting ::= "let" Var "=" Expr "in" Expr // let foo = 12 in ... - -Setting ::= Var ":=" Expr "in" Expr // foo := a in ... - -// we force every function have at least 1 argument. -Lambda ::= "fn" LambdaArgs "->" Expr // fn x y -> 12 - -LambdaArgs ::= Var | Var LambdaArgs - -Applying ::= Expr ExprArgs // foo 3 9 即foo(3, 9) - -ExprArgs ::= Expr | (Expr ExprArgs) - -Var ::= ID - -Const ::= String | Float | Integer - -ID ::= ("_" | [a-z] | [A-Z]) ("_" | [0-9] | [a-z] | [A-Z])+ - -Integer ::= [0-9]+ - -Float ::= [0-9]+ "." [0-9]+ - -String ::= '"' (不是「"」的任一字元|('\' '"')) '"' +FLO = \d+[.]\d+ // 浮點數 +INT = \d+ // 整數 +AT = '@' // @ +ID = [_\w][_\d\w]* // 識別子 +R_ARR = [-][>] // 右箭頭 -> +SEMICOLON = ";" +// 括號 +L_PAR = '(' +R_PAR = ')' +ASSIGN = '=' +OP = [+-*/] | [=][=] | [!<>][=] // 運算子 +HASH = [#] +COM = #[^#]*# # 註解 # +SPACE = \s+ # 空白字元 +B_SLASH = [\\] // 反斜線 +STR = \"([^"]|[\\\"])*\" +LIT_STR = ([^\\]?) // 文字模式的不貪婪模式 ``` -而上述的item可以被1個以上半形空白或tab(`\t`)以及1個「`\n`或`\r\n`」(換行符號)隔開。而為求簡化這些符號在MainTxt均指代一個半形空白。也就是空一個半形空白、兩個半形空白、一個tab、一個換行符號等等都會顯示如一個半形符號。而在Expr表達式區,把它忽略掉。另外兩個換行符號設定為換行指令,而這在Expr區會被忽略。所以要加另外兩條: - -``` -Space = (' ' | '\t')* | '\n' | '\r\n' -NewPara = = ('\n' |'\r' '\n' ) ('\n' |'\r' '\n' ) +程式語法定義如下: +```BNF +Main ::= (LitStr | Prog)* ; 主體 +LitStr ::= ( not(AT) | B_SLASH AT | B_SLATH HASH)+ ;基本文字模式 +Prog ::= '@' BODY '@' ;程式模式 +BODY ::= LET | EXPR | DEFINE +DEFINE ::= "define" TYPE VAR ASSIGN BODY SEMICOLON ; 全局定義 +LET ::= "let" TYPE VAR ASSIGN "in" BODY ; 局域定義 +EXPR ::= APPLY | FN | LIST | CONST | VAR | "(" EXPR ")" +APPLY ::= OP EXPR+ | EXPR EXPR+ +FN ::= "fn" ARGS R_ARR BODY +ARGS ::= ARG | ARG ARGS +ARG ::= "(" TYPE VAR ")" +CONST ::= FLO | STR | INT +VAR ::= ID +TYPE ::= ID +LIST ::= [LIST_INNER] +LIST_INNER ::= EXPR | EXPR SEMICOLON LIST_INNER ``` ## 用ts-parsec和regexp進行tokenize @@ -163,44 +155,7 @@ thenDo(thenDo(thenDo(sWrapped, match0to9), match0to9), match0to9) 我們編輯Node.js的進入點程式(假設為src/index.js`),底下為定義tokenizer的型別和regex pattern: ```typescript -/** the type of token */ -enum TokenKind { - Int, // 3 - Flo, // 3.1416 - Id, // foo, _123, etc - At, // @ - Comt, // comment /* - Str, /** "foo" */ - Assign, /** = */ - Set, /** := */ - Keyword, /** let, in */ - LParen, /** ( */ - RParen, /** ) */ - Space, /** semi-width space tab, \r\n? */ - NewPara, /** breaking paragraph, (\r\n?){2} */ - MainTxt, /** used in main text */ -} - -// tokenizer -const tokenizer = parsec.buildLexer([ - [true, /^\d+/g, TokenKind.Int], - [true, /^\d+\.\d+/g, TokenKind.Flo], - [true, /^(let|in)/g, TokenKind.Keyword], // let and in - [true, /^[_a-zA-Z][_0-9a-zA-Z]*/g, TokenKind.Id], - [true, /^\@/g, TokenKind.At], - /* inside comment, only accept 1. non / character - or 2. "/ + non * character" */ - [true, /^\/\*(\/[^*]|[^\\]?)*\*\//g, TokenKind.Comt], - [true, /^\"(\\\"|[^\"]?)*\"/g, TokenKind.Str], - [true, /^\:\=/g, TokenKind.Set], - [true, /^\=/g, TokenKind.Assign], - [true, /^\(/g, TokenKind.LParen], - [true, /^\)/g, TokenKind.RParen], - [true, /^([ \t]+|\n)/g, TokenKind.Space], - [true, /^(\r?\n){2}/g, TokenKind.NewPara], - [true, /^(\\\@|[^@\s])+/g, TokenKind.MainTxt], -]); ``` ### 常數parsing diff --git a/src/ch1/src/index.d.ts b/src/ch1/src/index.d.ts index 95ee14b..fb4fa60 100644 --- a/src/ch1/src/index.d.ts +++ b/src/ch1/src/index.d.ts @@ -1,23 +1,24 @@ -import * as parsec from 'typescript-parsec'; +import * as p from 'typescript-parsec'; /** the type of token */ declare enum TokenKind { - Int = 0, - Flo = 1, - Id = 2, - At = 3, - Comt = 4, - Str = /** "foo" */ 5, - Lambda = /** -> */ 6, - Assign = /** = */ 7, - Set = /** := */ 8, - Keyword = /** let, in */ 9, - LParen = /** ( */ 10, - RParen = /** ) */ 11, - Space = /** semi-width space tab, \r\n? */ 12, - NewPara = /** breaking paragraph, (\r\n?){2} */ 13, - MainTxt = /** used in main text */ 14 + Flo = 0, + Int = 1, + At = 2, + Id = 3, + RArr = 4, + SColon = 5, + LPar = 6, + RPar = 7, + Assign = 8, + Op = 9, + Hash = 10, + Com = 11, + BSlash = 12, + Str = 13, + LitStr = 14, + Space = 15 } -export interface ASTNode extends parsec.Token { +export interface ASTNode extends p.Token { actualValue?: bigint | number | string; } /** AST Tree */ diff --git a/src/ch1/src/index.js b/src/ch1/src/index.js index a710000..e60c19c 100644 --- a/src/ch1/src/index.js +++ b/src/ch1/src/index.js @@ -1,27 +1,28 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.astToSExp = void 0; -const parsec = require("typescript-parsec"); // import parsec +const p = require("typescript-parsec"); // import p /* for test */ const assert = require("assert"); /** the type of token */ var TokenKind; (function (TokenKind) { - TokenKind[TokenKind["Int"] = 0] = "Int"; - TokenKind[TokenKind["Flo"] = 1] = "Flo"; - TokenKind[TokenKind["Id"] = 2] = "Id"; - TokenKind[TokenKind["At"] = 3] = "At"; - TokenKind[TokenKind["Comt"] = 4] = "Comt"; - TokenKind[TokenKind["Str"] = 5] = "Str"; - TokenKind[TokenKind["Lambda"] = 6] = "Lambda"; - TokenKind[TokenKind["Assign"] = 7] = "Assign"; - TokenKind[TokenKind["Set"] = 8] = "Set"; - TokenKind[TokenKind["Keyword"] = 9] = "Keyword"; - TokenKind[TokenKind["LParen"] = 10] = "LParen"; - TokenKind[TokenKind["RParen"] = 11] = "RParen"; - TokenKind[TokenKind["Space"] = 12] = "Space"; - TokenKind[TokenKind["NewPara"] = 13] = "NewPara"; - TokenKind[TokenKind["MainTxt"] = 14] = "MainTxt"; + TokenKind[TokenKind["Flo"] = 0] = "Flo"; + TokenKind[TokenKind["Int"] = 1] = "Int"; + TokenKind[TokenKind["At"] = 2] = "At"; + TokenKind[TokenKind["Id"] = 3] = "Id"; + TokenKind[TokenKind["RArr"] = 4] = "RArr"; + TokenKind[TokenKind["SColon"] = 5] = "SColon"; + TokenKind[TokenKind["LPar"] = 6] = "LPar"; + TokenKind[TokenKind["RPar"] = 7] = "RPar"; + TokenKind[TokenKind["Assign"] = 8] = "Assign"; + TokenKind[TokenKind["Op"] = 9] = "Op"; + TokenKind[TokenKind["Hash"] = 10] = "Hash"; + TokenKind[TokenKind["Com"] = 11] = "Com"; + TokenKind[TokenKind["BSlash"] = 12] = "BSlash"; + TokenKind[TokenKind["Str"] = 13] = "Str"; + TokenKind[TokenKind["LitStr"] = 14] = "LitStr"; + TokenKind[TokenKind["Space"] = 15] = "Space"; })(TokenKind || (TokenKind = {})); /** from AST to S-exp */ function astToSExp(ast) { @@ -36,29 +37,29 @@ function astToSExp(ast) { } exports.astToSExp = astToSExp; // tokenizer -const tokenizer = parsec.buildLexer([ +const tokenizer = p.buildLexer([ + [true, /^\d+[.]\d+/g, TokenKind.Flo], [true, /^\d+/g, TokenKind.Int], - [true, /^\d+\.\d+/g, TokenKind.Flo], - [true, /^(let|in|fn)/g, TokenKind.Keyword], - [true, /^[_a-zA-Z][_0-9a-zA-Z]*/g, TokenKind.Id], - [true, /^\@/g, TokenKind.At], - /* inside comment, only accept 1. non / character - or 2. "/ + non * character" */ - [true, /^\/\*(\/[^*]|[^\\]?)*\*\//g, TokenKind.Comt], - [true, /^\"(\\\"|[^\"]?)*\"/g, TokenKind.Str], - [true, /^\:\=/g, TokenKind.Set], - [true, /^\=/g, TokenKind.Assign], - [true, /^->/g, TokenKind.Lambda], - [true, /^\(/g, TokenKind.LParen], - [true, /^\)/g, TokenKind.RParen], - [true, /^([ \t]+|[ \t]*\r?\n[ \t]*)/g, TokenKind.Space], - [true, /^(\r?\n){2}/g, TokenKind.NewPara], - [true, /^(\\\@|[^@\s])/g, TokenKind.MainTxt], + [true, /^[@]/g, TokenKind.At], + [true, /^[_\w][_\d\w]*/g, TokenKind.Id], + [true, /^->/g, TokenKind.RArr], + [true, /^[;]/g, TokenKind.SColon], + [true, /^[(]/g, TokenKind.LPar], + [true, /^[)]/g, TokenKind.RPar], + [true, /^[=]/g, TokenKind.Assign], + [true, /^([\+\-\*\/]|[!<>=]=)/g, TokenKind.Op], + [true, /^#[^#]*#/g, TokenKind.Com], + [true, /^[\\]/g, TokenKind.BSlash], + [true, /^\"([^"]|[\\\"])*\"/g, TokenKind.Str], + [true, /^([^\\]+?)/g, TokenKind.LitStr], + [true, /^\s+/g, TokenKind.Space], ]); /** ignore spaces ,new lines, and comments */ -const _ = parsec.opt(parsec.alt(parsec.tok(TokenKind.Space), parsec.tok(TokenKind.NewPara), -// space or newPara + comment + space or newPara -parsec.seq(parsec.opt(parsec.alt(parsec.tok(TokenKind.Space), parsec.tok(TokenKind.NewPara))), parsec.tok(TokenKind.Comt), parsec.opt(parsec.alt(parsec.tok(TokenKind.Space), parsec.tok(TokenKind.NewPara)))))); +//const _ = p.opt(p.alt( +// p.tok(TokenKind.Space), +// p.tok(TokenKind.Com), +// ) +//); function applyInteger(value) { // extend value to ASTNode const newNode = { @@ -82,112 +83,23 @@ function applyString(value) { }; return newNode; } -function applyIdentifier(value) { - const newNode = { - actualValue: value.text, - ...value - }; - return newNode; -} -/** apply LETTING. - * returns [let, [var, x], expr] */ -function applyLetting(input) { - // node representing let - let letNode = input[0]; - let varNode = input[2]; - let valueNode = input[6]; - let exprAST = input[10]; - return [letNode, [varNode, valueNode], exprAST]; -} -/** apply SETTING */ -function applySetting(input) { - // node representing let - let setNode = input[2]; - let varNode = input[0]; - let valueNode = input[4]; - let exprAST = input[8]; - // (:= (var val) expr) : set var = val in expr - return [setNode, [varNode, valueNode], exprAST]; -} -function applyLambda(input) { - let lambdaNode = input[0]; - let argHead = input[1]; - let argTail = input[2]; - let body = input[6]; - let args = [argHead].concat(argTail); - // return (fn (args) body) like lambda in Scheme - return [lambdaNode, args, body]; -} -function applyApplying(input) { - let applier = input[0]; - let applieeHead = input[2]; - let applieeTail = input[3]; - let appliee = [(applieeHead)].concat(applieeTail); - // foo 2 3 => (foo (2 3)) - return [applier, appliee]; -} /** define all the parser sentence */ -const CONST = parsec.rule(); -const VAR = parsec.rule(); -const ARG = parsec.rule(); -const EXPR = parsec.rule(); -const LETTING = parsec.rule(); -const SETTING = parsec.rule(); -const LAMBDA = parsec.rule(); -const APPLYING = parsec.rule(); -/* -CONST ::= INT | FLOAT | STRING -*/ -CONST.setPattern(parsec.alt(parsec.apply(parsec.tok(TokenKind.Int), applyInteger), parsec.apply(parsec.tok(TokenKind.Flo), applyFloat), parsec.apply(parsec.tok(TokenKind.Str), applyString))); -/** VAR = ID */ -VAR.setPattern(parsec.apply(parsec.tok(TokenKind.Id), applyIdentifier)); -/** ARG = ID */ -ARG.setPattern(parsec.apply(parsec.tok(TokenKind.Id), applyIdentifier)); -/**SETTING ::= VAR ":=" EXPR in EXPR - * and ignore the spaces and new lines with `_` -*/ -SETTING.setPattern(parsec.apply(parsec.seq(VAR, _, parsec.str(":="), _, EXPR, _, parsec.str("in"), _, EXPR), applySetting)); -/**LETTING ::= "let" VAR "=" EXPR in EXPR - * and ignore the spaces and new lines with `_` -*/ -LETTING.setPattern(parsec.apply(parsec.seq(parsec.str("let"), _, VAR, _, parsec.str("="), _, EXPR, _, parsec.str("in"), _, EXPR), applyLetting)); -/**LAMBDA ::= "fn" (Args)+ "->" EXPR - * and ignore the spaces and new lines with `_` -*/ -LAMBDA.setPattern(parsec.apply(parsec.seq(parsec.str("fn"), parsec.kright(_, ARG), // arg SpaceNL -parsec.rep_sc(parsec.kright(_, ARG)), //other (arg SpaceNL), repeat 0+times -_, parsec.str("->"), _, EXPR), applyLambda)); -// APPLYING = ( "(" APPLYING ")" |LAMBDA|VAR) APPLIEE+ -APPLYING.setPattern(parsec.apply(parsec.seq(parsec.alt(LAMBDA, VAR, parsec.kmid(parsec.seq(parsec.str('('), _), APPLYING, parsec.seq(_, parsec.str(')')))), _, EXPR, parsec.rep_sc(parsec.kright(_, EXPR))), applyApplying)); -/** EXPR = CONST | VAR - * | LETTING | SETTING - * | LAMBDA | APPLYING - * | "(" APPLYING ")" */ -EXPR.setPattern(parsec.alt(CONST, VAR, LETTING, SETTING, LAMBDA, parsec.kmid(parsec.seq(parsec.str('('), _), APPLYING, parsec.seq(_, parsec.str(')'))))); +const CONST = p.rule(); +/*const VAR = p.rule(); +const ARG = p.rule(); +const EXPR = p.rule(); +const LETTING = p.rule(); +const LAMBDA = p.rule(); +const APPLYING = p.rule(); */ +CONST.setPattern(p.alt(p.apply(p.tok(TokenKind.Flo), applyFloat), p.apply(p.tok(TokenKind.Int), applyInteger), p.apply(p.tok(TokenKind.Str), applyString))); function mainParse(inputStr) { - return parsec.expectSingleResult(parsec.expectEOF(EXPR.parse(tokenizer.parse(inputStr)))); + return p.expectSingleResult(p.expectEOF(CONST.parse(tokenizer.parse(inputStr)))); } // test function main() { - // bigint has suffix `n` - assert.strictEqual(mainParse('123455667').actualValue, 123455667n); - assert.strictEqual(mainParse('000').actualValue, 0n); - assert.strictEqual(mainParse('1.22').actualValue, 1.22); - assert.strictEqual(mainParse('0.0').actualValue, 0.0); - assert.strictEqual(mainParse(`""`).actualValue, ""); - assert.strictEqual(mainParse(`"the little town"`).actualValue, `the little town`); - assert.strictEqual(mainParse(`"\\\"Alice\\\""`).actualValue, `"Alice"`); - assert.strictEqual(mainParse(`foo`).actualValue, "foo"); - assert.strictEqual(astToSExp(mainParse(`let x = 12 in 23`)), "(let (x 12) 23)"); - assert.strictEqual(astToSExp(mainParse(`let y = 10 in let x = 12 in 23`)), "(let (y 10) (let (x 12) 23))"); - assert.strictEqual(astToSExp(mainParse(`let y = 10 in y := 12 in 23`)), "(let (y 10) (:= (y 12) 23))"); - assert.strictEqual(astToSExp(mainParse(`fn x y -> 234`)), "(fn (x y) 234)"); - assert.strictEqual(astToSExp(mainParse(`(add 12 23 )`)), "(add (12 23))"); - assert.strictEqual(astToSExp(mainParse(`(foo x y)`)), "(foo (x y))"); - assert.strictEqual(astToSExp(mainParse(`((foo 6 7) bar)`)), "((foo (6 7)) (bar))"); - assert.strictEqual(astToSExp(mainParse(`fn x y -> - /* foo bar */ - (foo x y)`)), "(fn (x y) (foo (x y)))"); + assert.strictEqual(mainParse("123").actualValue, 123n); + assert.strictEqual(mainParse("3.14").actualValue, 3.14); + assert.strictEqual(mainParse("\"foo\"").actualValue, "foo"); } ; main(); diff --git a/src/ch1/src/index.js.map b/src/ch1/src/index.js.map index 2dfcf61..93a77c1 100644 --- a/src/ch1/src/index.js.map +++ b/src/ch1/src/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAAA,4CAA4C,CAAC,gBAAgB;AAC7D,cAAc;AACd,iCAAiC;AAEjC,yBAAyB;AACzB,IAAK,SAgBJ;AAhBD,WAAK,SAAS;IACV,uCAAG,CAAA;IACH,uCAAG,CAAA;IACH,qCAAE,CAAA;IACF,qCAAE,CAAA;IACF,yCAAI,CAAA;IACJ,uCAAG,CAAA;IACH,6CAAM,CAAA;IACN,6CAAM,CAAA;IACN,uCAAG,CAAA;IACH,+CAAO,CAAA;IACP,8CAAM,CAAA;IACN,8CAAM,CAAA;IACN,4CAAK,CAAA;IACL,gDAAO,CAAA;IACP,gDAAO,CAAA;AACX,CAAC,EAhBI,SAAS,KAAT,SAAS,QAgBb;AAYD,wBAAwB;AACxB,SAAgB,SAAS,CAAC,GAAS;IAC/B,mBAAmB;IACnB,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAC;QACnB,OAAO,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAO,EAAC,EAAE,CAAA,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QAClE,iBAAiB;KAChB;SAAI;QACD,OAAO,GAAG,CAAC,IAAI,CAAC;KACnB;AACL,CAAC;AARD,8BAQC;AAGD,YAAY;AACZ,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC;IAChC,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC;IAC9B,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,GAAG,CAAC;IACnC,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,CAAC,OAAO,CAAC;IAC1C,CAAC,IAAI,EAAE,0BAA0B,EAAE,SAAS,CAAC,EAAE,CAAC;IAChD,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC;IAC5B;mCAC+B;IAC/B,CAAC,IAAI,EAAE,4BAA4B,EAAE,SAAS,CAAC,IAAI,CAAC;IACpD,CAAC,IAAI,EAAE,sBAAsB,EAAE,SAAS,CAAC,GAAG,CAAC;IAC7C,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,GAAG,CAAC;IAC/B,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;IAChC,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;IAChC,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;IAChC,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;IAChC,CAAC,IAAI,EAAE,8BAA8B,EAAE,SAAS,CAAC,KAAK,CAAC;IACvD,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,CAAC,OAAO,CAAC;IACzC,CAAC,IAAI,EAAE,iBAAiB,EAAE,SAAS,CAAC,OAAO,CAAC;CAC/C,CAAC,CAAC;AAGH,6CAA6C;AAC7C,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAC3B,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAC3B,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AAE7B,gDAAgD;AAChD,MAAM,CAAC,GAAG,CACN,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CACjB,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAC3B,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EACnC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAC1B,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CACjB,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAC3B,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAClC,CACJ,CACJ,CAAC;AAKF,SAAS,YAAY,CAAC,KAAkC;IACpD,0BAA0B;IAC1B,MAAM,OAAO,GAAc;QACvB,WAAW,EAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;QAChC,GAAG,KAAK;KAAC,CAAC;IACd,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,UAAU,CAAC,KAAkC;IAClD,MAAM,OAAO,GAAc;QACvB,WAAW,EAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;QACpC,GAAG,KAAK;KAAC,CAAC;IACd,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,WAAW,CAAC,KAAkC;IACnD,MAAM,OAAO,GAAc;QACvB,8CAA8C;QAC9C,WAAW,EAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC;QAC5E,GAAG,KAAK;KAAC,CAAC;IACd,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,KAAiC;IACtD,MAAM,OAAO,GAAc;QACvB,WAAW,EAAG,KAAK,CAAC,IAAI;QACxB,GAAG,KAAK;KAAC,CAAC;IACd,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;mCACmC;AACnC,SAAS,YAAY,CAAC,KAWO;IACzB,wBAAwB;IACxB,IAAI,OAAO,GAAa,KAAK,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,OAAO,GAAI,KAAK,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;IAExB,OAAO,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;AAEpD,CAAC;AAED,oBAAoB;AACpB,SAAS,YAAY,CAAC,KASO;IACzB,wBAAwB;IACxB,IAAI,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,OAAO,GAAI,KAAK,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEvB,+CAA+C;IAC/C,OAAO,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;AAEpD,CAAC;AAED,SAAS,WAAW,CAAC,KAOpB;IACG,IAAI,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAEpC,gDAAgD;IAChD,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAGD,SAAS,aAAa,CAAC,KAIlB;IACD,IAAI,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,OAAO,GAAG,CAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAGvD,yBAAyB;IACzB,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAE9B,CAAC;AAED,qCAAqC;AACrC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAsB,CAAC;AAChD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAsB,CAAC;AAC9C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAsB,CAAC;AAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAkB,CAAC;AAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAkB,CAAC;AAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAkB,CAAC;AAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAkB,CAAC;AAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAkB,CAAC;AAI/C;;EAEE;AACF,KAAK,CAAC,UAAU,CACZ,MAAM,CAAC,GAAG,CACN,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,EACrD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,EACnD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CACvD,CACJ,CAAC;AAEF,gBAAgB;AAChB,GAAG,CAAC,UAAU,CACN,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,eAAe,CAAC,CAC9D,CAAC;AAEF,gBAAgB;AAChB,GAAG,CAAC,UAAU,CACV,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,eAAe,CAAC,CAC1D,CAAC;AAKF;;EAEE;AAEF,OAAO,CAAC,UAAU,CACd,MAAM,CAAC,KAAK,CACR,MAAM,CAAC,GAAG,CACV,GAAG,EACH,CAAC,EACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAChB,CAAC,EACD,IAAI,EACJ,CAAC,EACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAChB,CAAC,EACD,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;AAE9B;;EAEE;AACF,OAAO,CAAC,UAAU,CACd,MAAM,CAAC,KAAK,CACR,MAAM,CAAC,GAAG,CACV,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EACjB,CAAC,EACD,GAAG,EACH,CAAC,EACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EACf,CAAC,EACD,IAAI,EACJ,CAAC,EACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAChB,CAAC,EACD,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;AAI9B;;EAEE;AACF,MAAM,CAAC,UAAU,CACb,MAAM,CAAC,KAAK,CACR,MAAM,CAAC,GAAG,CACN,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAChB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,cAAc;AACrC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,qCAAqC;AAC3E,CAAC,EACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAChB,CAAC,EACD,IAAI,CAAC,EACb,WAAW,CAAC,CACf,CAAA;AAED,sDAAsD;AACtD,QAAQ,CAAC,UAAU,CACf,MAAM,CAAC,KAAK,CACR,MAAM,CAAC,GAAG,CACN,MAAM,CAAC,GAAG,CACN,MAAM,EACN,GAAG,EACH,MAAM,CAAC,IAAI,CACP,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAC9B,QAAQ,EACR,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CACtC,EACD,CAAC,EACD,IAAI,EACJ,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,EAC1C,aAAa,CAAC,CAAC,CAAC;AAExB;;;wBAGwB;AACxB,IAAI,CAAC,UAAU,CACX,MAAM,CAAC,GAAG,CACP,KAAK,EACL,GAAG,EACH,OAAO,EACP,OAAO,EACP,MAAM,EACL,MAAM,CAAC,IAAI,CACP,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAC9B,QAAQ,EACR,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CACtC,CACJ,CAAC;AAMF,SAAS,SAAS,CAAC,QAAiB;IAChC,OAAO,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAC7C,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAGD,OAAO;AACP,SAAS,IAAI;IACT,wBAAwB;IACxB,MAAM,CAAC,WAAW,CAAW,SAAS,CAAC,WAAW,CAAE,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAC9E,MAAM,CAAC,WAAW,CAAW,SAAS,CAAC,KAAK,CAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAChE,MAAM,CAAC,WAAW,CAAW,SAAS,CAAC,MAAM,CAAE,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACnE,MAAM,CAAC,WAAW,CAAW,SAAS,CAAC,KAAK,CAAE,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,CAAC,WAAW,CAAW,SAAS,CAAC,IAAI,CAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC/D,MAAM,CAAC,WAAW,CAAW,SAAS,CAAC,mBAAmB,CAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;IAC7F,MAAM,CAAC,WAAW,CAAW,SAAS,CAAC,iBAAiB,CAAE,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAEnF,MAAM,CAAC,WAAW,CAAW,SAAS,CAAC,KAAK,CAAE,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACnE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;IAChF,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC,EAAE,8BAA8B,CAAC,CAAC;IAC3G,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC,EAAE,6BAA6B,CAAC,CAAC;IACvG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC5E,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;IAC1E,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IACrE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;IACnF,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC;;cAE7B,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC;AAG5C,CAAC;AAAA,CAAC;AAEF,IAAI,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/ch1/src/index.ts b/src/ch1/src/index.ts index bbabf63..c46f820 100644 --- a/src/ch1/src/index.ts +++ b/src/ch1/src/index.ts @@ -1,28 +1,29 @@ -import * as parsec from 'typescript-parsec'; // import parsec +import * as p from 'typescript-parsec'; // import p /* for test */ import * as assert from 'assert'; /** the type of token */ enum TokenKind { - Int, // 3 - Flo, // 3.1416 - Id, // foo, _123, etc + Flo, + Int, At, // @ - Comt, // comment /* - Str, /** "foo" */ - Lambda, /** -> */ - Assign, /** = */ - Set, /** := */ - Keyword, /** let, in */ - LParen, /** ( */ - RParen, /** ) */ - Space, /** semi-width space tab, \r\n? */ - NewPara, /** breaking paragraph, (\r\n?){2} */ - MainTxt, /** used in main text */ + Id, // identifier + RArr, // Right Arrow + SColon, // Semi colon + LPar, // left perenthesis + RPar, // right paranthesis + Assign, // = + Op, // +-*/... + Hash, // # + Com, // # comment + BSlash, // backslash\ + Str, // "string" + LitStr, // literal string + Space, // Spaces } // add "actualValue" in the parsed Token -export interface ASTNode extends parsec.Token{ +export interface ASTNode extends p.Token{ // number is for float number; //it's optional. since keyword has no value actualValue? : bigint | number | string; @@ -44,49 +45,36 @@ export function astToSExp(ast : AST){ // tokenizer -const tokenizer = parsec.buildLexer([ +const tokenizer = p.buildLexer([ + [true,/^\d+[.]\d+/g , TokenKind.Flo], [true, /^\d+/g, TokenKind.Int], - [true, /^\d+\.\d+/g, TokenKind.Flo], - [true, /^(let|in|fn)/g, TokenKind.Keyword], // let, in, fn - [true, /^[_a-zA-Z][_0-9a-zA-Z]*/g, TokenKind.Id], - [true, /^\@/g, TokenKind.At], - /* inside comment, only accept 1. non / character - or 2. "/ + non * character" */ - [true, /^\/\*(\/[^*]|[^\\]?)*\*\//g, TokenKind.Comt], - [true, /^\"(\\\"|[^\"]?)*\"/g, TokenKind.Str], - [true, /^\:\=/g, TokenKind.Set], - [true, /^\=/g, TokenKind.Assign], - [true, /^->/g, TokenKind.Lambda], - [true, /^\(/g, TokenKind.LParen], - [true, /^\)/g, TokenKind.RParen], - [true, /^([ \t]+|[ \t]*\r?\n[ \t]*)/g, TokenKind.Space], - [true, /^(\r?\n){2}/g, TokenKind.NewPara], - [true, /^(\\\@|[^@\s])/g, TokenKind.MainTxt], + [true,/^[@]/g, TokenKind.At ], + [true,/^[_\w][_\d\w]*/g, TokenKind.Id ], + [true,/^->/g , TokenKind.RArr ], + [true, /^[;]/g, TokenKind.SColon ], + [true, /^[(]/g, TokenKind.LPar ], + [true, /^[)]/g, TokenKind.RPar ], + [true, /^[=]/g, TokenKind.Assign ], + [true, /^([\+\-\*\/]|[!<>=]=)/g, TokenKind.Op ], + [true, /^#[^#]*#/g, TokenKind.Com ], + [true, /^[\\]/g, TokenKind.BSlash ], + [true,/^\"([^"]|[\\\"])*\"/g , TokenKind.Str ], + [true, /^([^\\]+?)/g, TokenKind.LitStr ], + [true, /^\s+/g, TokenKind.Space], ]); -/** ignore spaces ,new lines, and comments */ -const _ = parsec.opt(parsec.alt( - parsec.tok(TokenKind.Space), - parsec.tok(TokenKind.NewPara), - - // space or newPara + comment + space or newPara - parsec.seq( - parsec.opt(parsec.alt( - parsec.tok(TokenKind.Space), - parsec.tok(TokenKind.NewPara))), - parsec.tok(TokenKind.Comt), - parsec.opt(parsec.alt( - parsec.tok(TokenKind.Space), - parsec.tok(TokenKind.NewPara))), - ) - ) -); +/** ignore spaces ,new lines, and comments */ +//const _ = p.opt(p.alt( +// p.tok(TokenKind.Space), +// p.tok(TokenKind.Com), +// ) +//); -function applyInteger(value: parsec.Token): ASTNode { +function applyInteger(value: p.Token): ASTNode { // extend value to ASTNode const newNode : ASTNode = { actualValue : BigInt(value.text) , @@ -94,14 +82,14 @@ function applyInteger(value: parsec.Token): ASTNode { return newNode; } -function applyFloat(value: parsec.Token): ASTNode { +function applyFloat(value: p.Token): ASTNode { const newNode : ASTNode = { actualValue : parseFloat(value.text) , ...value}; return newNode; } -function applyString(value: parsec.Token): ASTNode { +function applyString(value: p.Token): ASTNode { const newNode : ASTNode = { // get only text[1,2,...,the second last char] actualValue : value.text.slice(1,value.text.length-1).replace(/\\\"/g, "\"") , @@ -109,250 +97,36 @@ function applyString(value: parsec.Token): ASTNode { return newNode; } -function applyIdentifier(value: parsec.Token): ASTNode { - const newNode : ASTNode = { - actualValue : value.text, - ...value}; - return newNode; -} - -/** apply LETTING. - * returns [let, [var, x], expr] */ -function applyLetting(input: [parsec.Token, // let - parsec.Token | undefined, // space - ASTNode, // var - parsec.Token| undefined, // space - parsec.Token, // = - parsec.Token| undefined, // space - AST, // val - parsec.Token| undefined, // space - parsec.Token, // in - parsec.Token| undefined, // space - AST // expr - ]): AST { - // node representing let - let letNode : ASTNode = input[0]; - let varNode = input[2]; - let valueNode = input[6]; - let exprAST = input[10]; - - return [letNode, [varNode, valueNode], exprAST]; - -} - -/** apply SETTING */ -function applySetting(input: [ASTNode, // var - parsec.Token| undefined, // space - parsec.Token, // := - parsec.Token| undefined, // space - AST, // val - parsec.Token| undefined, // space - parsec.Token, // in - parsec.Token| undefined, // space - AST // expr - ]): AST { - // node representing let - let setNode = input[2]; - let varNode = input[0]; - let valueNode = input[4]; - let exprAST = input[8]; - - // (:= (var val) expr) : set var = val in expr - return [setNode, [varNode, valueNode], exprAST]; - -} - -function applyLambda(input: [ASTNode, // fn - ASTNode, // arg - ASTNode[], // args - parsec.Token| undefined, // space - parsec.Token, // -> - parsec.Token| undefined, // space - AST // expr -]): AST { - let lambdaNode = input[0]; - let argHead = input[1]; - let argTail = input[2]; - let body = input[6]; - let args = [argHead].concat(argTail) - - // return (fn (args) body) like lambda in Scheme - return [lambdaNode, args, body]; -} - - -function applyApplying(input : [ASTNode, // caller - parsec.Token |undefined, // space - ASTNode, // head of callee - AST[] // tail of callee - ]){ - let applier = input[0]; - let applieeHead = input[2]; - let applieeTail = input[3]; - let appliee = [(applieeHead)].concat(applieeTail); - - - // foo 2 3 => (foo (2 3)) - return [applier, appliee]; - -} - /** define all the parser sentence */ -const CONST = parsec.rule(); -const VAR = parsec.rule(); -const ARG = parsec.rule(); -const EXPR = parsec.rule(); -const LETTING = parsec.rule(); -const SETTING = parsec.rule(); -const LAMBDA = parsec.rule(); -const APPLYING = parsec.rule(); - +const CONST = p.rule(); +/*const VAR = p.rule(); +const ARG = p.rule(); +const EXPR = p.rule(); +const LETTING = p.rule(); +const LAMBDA = p.rule(); +const APPLYING = p.rule(); */ - -/* -CONST ::= INT | FLOAT | STRING -*/ CONST.setPattern( - parsec.alt( - parsec.apply(parsec.tok(TokenKind.Int), applyInteger), - parsec.apply(parsec.tok(TokenKind.Flo), applyFloat), - parsec.apply(parsec.tok(TokenKind.Str), applyString), - ) -); - -/** VAR = ID */ -VAR.setPattern( - parsec.apply(parsec.tok(TokenKind.Id), applyIdentifier), -); - -/** ARG = ID */ -ARG.setPattern( - parsec.apply(parsec.tok(TokenKind.Id), applyIdentifier), -); - - + p.alt( + p.apply(p.tok(TokenKind.Flo), applyFloat), + p.apply(p.tok(TokenKind.Int), applyInteger), + p.apply(p.tok(TokenKind.Str), applyString), - -/**SETTING ::= VAR ":=" EXPR in EXPR - * and ignore the spaces and new lines with `_` -*/ - -SETTING.setPattern( - parsec.apply( - parsec.seq( - VAR, - _, - parsec.str(":="), - _, - EXPR, - _, - parsec.str("in"), - _, - EXPR), applySetting)); - -/**LETTING ::= "let" VAR "=" EXPR in EXPR - * and ignore the spaces and new lines with `_` -*/ -LETTING.setPattern( - parsec.apply( - parsec.seq( - parsec.str("let"), - _, - VAR, - _, - parsec.str("="), - _, - EXPR, - _, - parsec.str("in"), - _, - EXPR), applyLetting)); - - - -/**LAMBDA ::= "fn" (Args)+ "->" EXPR - * and ignore the spaces and new lines with `_` -*/ -LAMBDA.setPattern( - parsec.apply( - parsec.seq( - parsec.str("fn"), - parsec.kright(_, ARG), // arg SpaceNL - parsec.rep_sc(parsec.kright(_, ARG)), //other (arg SpaceNL), repeat 0+times - _, - parsec.str("->"), - _, - EXPR), - applyLambda) -) - -// APPLYING = ( "(" APPLYING ")" |LAMBDA|VAR) APPLIEE+ -APPLYING.setPattern( - parsec.apply( - parsec.seq( - parsec.alt( - LAMBDA, - VAR, - parsec.kmid( - parsec.seq(parsec.str('('), _), - APPLYING, - parsec.seq(_, parsec.str(')'))) - ), - _, - EXPR, - parsec.rep_sc(parsec.kright(_, EXPR))), - applyApplying)); - -/** EXPR = CONST | VAR - * | LETTING | SETTING - * | LAMBDA | APPLYING - * | "(" APPLYING ")" */ -EXPR.setPattern( - parsec.alt( - CONST, - VAR, - LETTING, - SETTING, - LAMBDA, - parsec.kmid( - parsec.seq(parsec.str('('), _), - APPLYING, - parsec.seq(_, parsec.str(')'))) ) ); - - - function mainParse(inputStr : string){ - return parsec.expectSingleResult(parsec.expectEOF( - EXPR.parse(tokenizer.parse(inputStr)))); +return p.expectSingleResult(p.expectEOF( + CONST.parse(tokenizer.parse(inputStr)))); } // test function main(){ - // bigint has suffix `n` - assert.strictEqual((mainParse('123455667')).actualValue, 123455667n); - assert.strictEqual((mainParse('000')).actualValue, 0n); - assert.strictEqual((mainParse('1.22')).actualValue, 1.22); - assert.strictEqual((mainParse('0.0')).actualValue, 0.0); - assert.strictEqual((mainParse(`""`)).actualValue, ""); - assert.strictEqual((mainParse(`"the little town"`)).actualValue, `the little town`); - assert.strictEqual((mainParse(`"\\\"Alice\\\""`)).actualValue, `"Alice"`); - - assert.strictEqual((mainParse(`foo`)).actualValue, "foo"); - assert.strictEqual(astToSExp(mainParse(`let x = 12 in 23`)), "(let (x 12) 23)"); - assert.strictEqual(astToSExp(mainParse(`let y = 10 in let x = 12 in 23`)), "(let (y 10) (let (x 12) 23))"); - assert.strictEqual(astToSExp(mainParse(`let y = 10 in y := 12 in 23`)), "(let (y 10) (:= (y 12) 23))"); - assert.strictEqual(astToSExp(mainParse(`fn x y -> 234`)), "(fn (x y) 234)"); - assert.strictEqual(astToSExp(mainParse(`(add 12 23 )`)), "(add (12 23))"); - assert.strictEqual(astToSExp(mainParse(`(foo x y)`)), "(foo (x y))"); - assert.strictEqual(astToSExp(mainParse(`((foo 6 7) bar)`)), "((foo (6 7)) (bar))"); - assert.strictEqual(astToSExp(mainParse(`fn x y -> - /* foo bar */ - (foo x y)`)), "(fn (x y) (foo (x y)))"); + assert.strictEqual(mainParse("123").actualValue, 123n); + assert.strictEqual(mainParse("3.14").actualValue, 3.14); + assert.strictEqual(mainParse("\"foo\"").actualValue, "foo"); };