toylang
Version:
A toy programming language built with TypeScript for learning purposes
141 lines (140 loc) • 6.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseEmptyStatement = exports.parseReturnStatement = exports.parseFunctionArguments = exports.parseArgumentList = exports.parseArguments = exports.parseIfStatement = exports.parseStatementList = exports.parseFunctionStatement = exports.parseBlockStatement = exports.parseExpressionStatement = exports.parseStatement = void 0;
var Tokenizer_1 = require("../Tokenizer");
var class_1 = require("./class");
var expression_1 = require("./expression");
var identifiers_1 = require("./identifiers");
var iterations_1 = require("./iterations");
var variable_1 = require("./variable");
function parseStatement(parser) {
var _a;
switch ((_a = parser._lookahead) === null || _a === void 0 ? void 0 : _a.type) {
case Tokenizer_1.TokenTypes.let:
return variable_1.parseVariableStatement(parser);
case Tokenizer_1.TokenTypes.if:
return parseIfStatement(parser);
case Tokenizer_1.TokenTypes.do:
case Tokenizer_1.TokenTypes.while:
case Tokenizer_1.TokenTypes.for:
return iterations_1.parseIterationStatement(parser);
case Tokenizer_1.TokenTypes.def:
return parseFunctionStatement(parser);
case Tokenizer_1.TokenTypes.return:
return parseReturnStatement(parser);
case Tokenizer_1.TokenTypes.class:
return class_1.parseClassDeclaration(parser);
case Tokenizer_1.TokenTypes.SEMI:
return parseEmptyStatement(parser);
case Tokenizer_1.TokenTypes.CURLY_START:
return parseBlockStatement(parser);
default:
return parseExpressionStatement(parser);
}
}
exports.parseStatement = parseStatement;
function parseExpressionStatement(parser) {
var expression = expression_1.parseExpression(parser);
parser._eat(Tokenizer_1.TokenTypes.SEMI);
return parser.factory.ExpressionStatement(expression);
}
exports.parseExpressionStatement = parseExpressionStatement;
function parseBlockStatement(parser) {
var _a;
// { OptStatementList }
parser._eat(Tokenizer_1.TokenTypes.CURLY_START);
var body = ((_a = parser._lookahead) === null || _a === void 0 ? void 0 : _a.type) !== Tokenizer_1.TokenTypes.CURLY_END
? parseStatementList(parser, Tokenizer_1.TokenTypes.CURLY_END)
: [];
parser._eat(Tokenizer_1.TokenTypes.CURLY_END);
return parser.factory.BlockStatement(body);
}
exports.parseBlockStatement = parseBlockStatement;
// `def` Identifier `(` OptFunctionArguments `)` BlockStatement
function parseFunctionStatement(parser) {
var _a;
parser._eat(Tokenizer_1.TokenTypes.def);
var name = identifiers_1.parseIdentifier(parser);
parser._eat(Tokenizer_1.TokenTypes.PAREN_START);
var params = ((_a = parser._lookahead) === null || _a === void 0 ? void 0 : _a.type) === Tokenizer_1.TokenTypes.PAREN_END
? []
: parseFunctionArguments(parser);
parser._eat(Tokenizer_1.TokenTypes.PAREN_END);
var body = parseBlockStatement(parser);
return parser.factory.FunctionStatement(name, body, params);
}
exports.parseFunctionStatement = parseFunctionStatement;
function parseStatementList(parser, stopLookhead) {
var _a;
var statementList = [parseStatement(parser)];
while (parser._lookahead !== null &&
((_a = parser._lookahead) === null || _a === void 0 ? void 0 : _a.type) !== stopLookhead) {
statementList.push(parseStatement(parser));
}
return statementList;
}
exports.parseStatementList = parseStatementList;
// `if` `(` Expression `)` Statement
// `if` `(` Expression `)` Statement `else` Statement
function parseIfStatement(parser) {
var _a;
parser._eat(Tokenizer_1.TokenTypes.if);
parser._eat(Tokenizer_1.TokenTypes.PAREN_START);
var expression = expression_1.parseExpression(parser);
parser._eat(Tokenizer_1.TokenTypes.PAREN_END);
var statement = parseStatement(parser);
var alternate = null;
if (((_a = parser._lookahead) === null || _a === void 0 ? void 0 : _a.type) === Tokenizer_1.TokenTypes.else) {
parser._eat(Tokenizer_1.TokenTypes.else);
alternate = parseStatement(parser);
}
return parser.factory.IfStatement(expression, statement, alternate);
}
exports.parseIfStatement = parseIfStatement;
// `(` OptArgumentList `)`
function parseArguments(parser) {
var _a;
parser._eat(Tokenizer_1.TokenTypes.PAREN_START);
var argumentList = ((_a = parser._lookahead) === null || _a === void 0 ? void 0 : _a.type) === Tokenizer_1.TokenTypes.PAREN_END
? []
: parseArgumentList(parser);
parser._eat(Tokenizer_1.TokenTypes.PAREN_END);
return argumentList;
}
exports.parseArguments = parseArguments;
// Expression, Expression
function parseArgumentList(parser) {
var _a;
var argumentList = [];
do {
argumentList.push(expression_1.parseAssignmentExpression(parser));
} while (((_a = parser._lookahead) === null || _a === void 0 ? void 0 : _a.type) === Tokenizer_1.TokenTypes.COMMA &&
parser._eat(Tokenizer_1.TokenTypes.COMMA));
return argumentList;
}
exports.parseArgumentList = parseArgumentList;
function parseFunctionArguments(parser) {
var _a;
var params = [];
do {
params.push(identifiers_1.parseIdentifier(parser));
} while (((_a = parser._lookahead) === null || _a === void 0 ? void 0 : _a.type) === Tokenizer_1.TokenTypes.COMMA &&
parser._eat(Tokenizer_1.TokenTypes.COMMA));
return params;
}
exports.parseFunctionArguments = parseFunctionArguments;
function parseReturnStatement(parser) {
var _a;
parser._eat(Tokenizer_1.TokenTypes.return);
var argument = ((_a = parser._lookahead) === null || _a === void 0 ? void 0 : _a.type) === Tokenizer_1.TokenTypes.SEMI
? null
: expression_1.parseExpression(parser);
parser._eat(Tokenizer_1.TokenTypes.SEMI);
return parser.factory.ReturnStatement(argument);
}
exports.parseReturnStatement = parseReturnStatement;
function parseEmptyStatement(parser) {
parser._eat(Tokenizer_1.TokenTypes.SEMI);
return parser.factory.EmptyStatement();
}
exports.parseEmptyStatement = parseEmptyStatement;