UNPKG

toylang

Version:

A toy programming language built with TypeScript for learning purposes

141 lines (140 loc) 6.35 kB
"use strict"; 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;