- Use the
astexplorerto understand tokens/AST - Use the
TS AST Viewerto understand the AST nodes (check text, symbols/declarations) - Read the
ECMAScript specification - Use the
ts playgroundto see the JS output - Run
npm run test:file test-filename.tsto debug only one test at a time. Replace thetest-filename.tswith the test file name you want to test - Add the baselines and run
npm run testand compare the local with the references
- scan forward all
- \t - tabs
- \b - empty strings at the beginning and end of a word
- \n - newline char
- if at the end of input, it's a
EOFtoken - if numbers, scan all numbers, add the number to the
text, and theNumericLiteraltoken to thetoken - if alphabetical chars, scan all chars, add the string to the
text, and the token can be aKeywordor anIdentifier - scan tokens like
Equals,Semicolon,Colon, etc - if not in the list, it's a
Unknowntoken
- Use the lexer to walkthrough the tokens and create the AST nodes
- Parse statements
- Var statements
- type statements
- expressions
- Var AST node
- name -> identifier
- typename -> type definition (if there's no
Colontoken, thetypenameshould beundefined) - init -> the value
- pos -> position
Source code: s;
{
"kind": "Identifier",
"text": "s"
}Source code: 1;
{
"kind": "NumericLiteral",
"value": 1
}Source code: example = 2;
{
"kind": "Assignment",
"name": {
"kind": "Identifier",
"text": "example"
},
"value": {
"kind": "NumericLiteral",
"value": 2
}
}Source code: example = 2;
{
"kind": "ExpressionStatement",
"expr": {
"kind": "Assignment",
"name": {
"kind": "Identifier",
"text": "arthurTwoShedsJackson"
},
"value": {
"kind": "NumericLiteral",
"value": 2
}
}
}Source code: var s: string = 1;
{
"kind": "Var",
"name": {
"kind": "Identifier",
"text": "s"
},
"typename": {
"kind": "Identifier",
"text": "string"
},
"init": {
"kind": "NumericLiteral",
"value": 1
}
}Source code: var s = 1;
{
"kind": "Var",
"name": {
"kind": "Identifier",
"text": "s"
},
"init": {
"kind": "NumericLiteral",
"value": 1
}
}Source code: type Int = number;
{
"kind": "TypeAlias",
"name": {
"kind": "Identifier",
"text": "Int"
},
"typename": {
"kind": "Identifier",
"text": "number"
}
}Source code: type Int = number; var int: Int = 10;
{
"kind": "Var",
"name": {
"kind": "Identifier",
"text": "int"
},
"typename": {
"kind": "Identifier",
"text": "Int"
},
"init": {
"kind": "NumericLiteral",
"value": 10
}
}checkExpression- when it's a
varnode- runs
checkExpressionto get the type of the expression'svalue - runs
checkTypeto get the type of thetypename - if there's no
typename, it should just return thevalue's type - if there's the
typename, compare thetypename's type with the thevalue's type- if there's a mismatch, add a new type error to the compiler
- runs
- when it's a
expressionnode- runs
checkExpression
- runs