petcarescript
Version:
PetCareScript - A modern, expressive programming language designed for humans
265 lines (246 loc) • 7.46 kB
JavaScript
/**
* PetCareScript Tokens
* Definitions of all token types in the language
*/
const TokenType = {
// Single-character tokens
LEFT_PAREN: 'LEFT_PAREN',
RIGHT_PAREN: 'RIGHT_PAREN',
LEFT_BRACE: 'LEFT_BRACE',
RIGHT_BRACE: 'RIGHT_BRACE',
LEFT_BRACKET: 'LEFT_BRACKET',
RIGHT_BRACKET: 'RIGHT_BRACKET',
COMMA: 'COMMA',
DOT: 'DOT',
MINUS: 'MINUS',
PLUS: 'PLUS',
SEMICOLON: 'SEMICOLON',
SLASH: 'SLASH',
STAR: 'STAR',
COLON: 'COLON',
PERCENT: 'PERCENT',
QUESTION: 'QUESTION',
AT: 'AT',
HASH: 'HASH',
AMPERSAND: 'AMPERSAND',
PIPE: 'PIPE',
// One or two character tokens
BANG: 'BANG',
BANG_EQUAL: 'BANG_EQUAL',
EQUAL: 'EQUAL',
EQUAL_EQUAL: 'EQUAL_EQUAL',
EQUAL_EQUAL_EQUAL: 'EQUAL_EQUAL_EQUAL',
GREATER: 'GREATER',
GREATER_EQUAL: 'GREATER_EQUAL',
LESS: 'LESS',
LESS_EQUAL: 'LESS_EQUAL',
ARROW: 'ARROW',
PLUS_PLUS: 'PLUS_PLUS',
MINUS_MINUS: 'MINUS_MINUS',
PLUS_EQUAL: 'PLUS_EQUAL',
MINUS_EQUAL: 'MINUS_EQUAL',
AND_AND: 'AND_AND',
OR_OR: 'OR_OR',
DOT_DOT_DOT: 'DOT_DOT_DOT', // Spread operator
// Literals
IDENTIFIER: 'IDENTIFIER',
STRING: 'STRING',
NUMBER: 'NUMBER',
TEMPLATE_STRING: 'TEMPLATE_STRING',
TEMPLATE_EXPRESSION: 'TEMPLATE_EXPRESSION',
TEMPLATE_END: 'TEMPLATE_END',
// Keywords - PetCareScript unique syntax
STORE: 'STORE',
WHEN: 'WHEN',
OTHERWISE: 'OTHERWISE',
REPEAT: 'REPEAT',
LOOP: 'LOOP',
AGAIN: 'AGAIN',
UNTIL: 'UNTIL',
UNLESS: 'UNLESS',
FOREACH: 'FOREACH',
BUILD: 'BUILD',
GIVE: 'GIVE',
YES: 'YES',
NO: 'NO',
EMPTY: 'EMPTY',
SHOW: 'SHOW',
BLUEPRINT: 'BLUEPRINT',
SELF: 'SELF',
PARENT: 'PARENT',
ALSO: 'ALSO',
EITHER: 'EITHER',
AND: 'AND',
OR: 'OR',
NOT: 'NOT',
IS: 'IS',
ISNT: 'ISNT',
BETWEEN: 'BETWEEN',
CONTAINS: 'CONTAINS',
LIKE: 'LIKE',
BREAK: 'BREAK',
CONTINUE: 'CONTINUE',
IMPORT: 'IMPORT',
EXPORT: 'EXPORT',
ATTEMPT: 'ATTEMPT',
CATCH: 'CATCH',
FINALLY: 'FINALLY',
THROW: 'THROW',
SWITCH: 'SWITCH',
CASE: 'CASE',
DEFAULT: 'DEFAULT',
// Type system
INTERFACE: 'INTERFACE',
ENUM: 'ENUM',
TYPE: 'TYPE',
NAMESPACE: 'NAMESPACE',
MODULE: 'MODULE',
VOID: 'VOID',
// JavaScript-style alternatives
ASYNC: 'ASYNC',
AWAIT: 'AWAIT',
TRY: 'TRY',
CLASS: 'CLASS',
FUNCTION: 'FUNCTION',
LET: 'LET',
CONST: 'CONST',
VAR: 'VAR',
IF: 'IF',
ELSE: 'ELSE',
WHILE: 'WHILE',
FOR: 'FOR',
RETURN: 'RETURN',
TRUE: 'TRUE',
FALSE: 'FALSE',
NULL: 'NULL',
UNDEFINED: 'UNDEFINED',
THIS: 'THIS',
SUPER: 'SUPER',
NEW: 'NEW',
DELETE: 'DELETE',
INSTANCEOF: 'INSTANCEOF',
IN: 'IN',
OF: 'OF',
STATIC: 'STATIC',
PUBLIC: 'PUBLIC',
PRIVATE: 'PRIVATE',
PROTECTED: 'PROTECTED',
EXTENDS: 'EXTENDS',
IMPLEMENTS: 'IMPLEMENTS',
FROM: 'FROM',
AS: 'AS',
WITH: 'WITH',
DO: 'DO',
GOTO: 'GOTO',
LABEL: 'LABEL',
YIELD: 'YIELD',
GENERATOR: 'GENERATOR',
CONSOLE: 'CONSOLE',
// Testing keywords
DESCRIBE: 'DESCRIBE',
IT: 'IT',
EXPECT: 'EXPECT',
MOCK: 'MOCK',
SPY: 'SPY',
ASSERT: 'ASSERT',
BEFORE: 'BEFORE',
AFTER: 'AFTER',
BEFORE_EACH: 'BEFORE_EACH',
AFTER_EACH: 'AFTER_EACH',
// Decorator keywords
DECORATOR: 'DECORATOR',
MEMOIZE: 'MEMOIZE',
TIMEOUT: 'TIMEOUT',
RETRY: 'RETRY',
// HTTP keywords
SERVER: 'SERVER',
ROUTE: 'ROUTE',
MIDDLEWARE: 'MIDDLEWARE',
CORS: 'CORS',
JSON: 'JSON',
LOGGER: 'LOGGER',
CREATE_SERVER: 'CREATE_SERVER',
GET: 'GET',
POST: 'POST',
PUT: 'PUT',
DELETE_HTTP: 'DELETE_HTTP',
PATCH: 'PATCH',
USE: 'USE',
LISTEN: 'LISTEN',
// Database keywords - REMOVIDOS da lista de keywords
// Agora connect, query, select, insert, update, delete, create, table, database, transaction
// são tratados como identificadores normais
// Promise keywords
PROMISE: 'PROMISE',
THEN: 'THEN',
RESOLVE: 'RESOLVE',
REJECT: 'REJECT',
ALL: 'ALL',
RACE: 'RACE',
PARALLEL: 'PARALLEL',
EOF: 'EOF'
};
class Token {
constructor(type, lexeme, literal, line, column) {
this.type = type;
this.lexeme = lexeme;
this.literal = literal;
this.line = line || 1;
this.column = column || 1;
}
toString() {
return `${this.type} ${this.lexeme} ${this.literal}`;
}
// Check if token is of given type(s)
is(...types) {
return types.includes(this.type);
}
// Check if token matches a keyword
isKeyword() {
const keywords = [
TokenType.STORE, TokenType.WHEN, TokenType.OTHERWISE, TokenType.REPEAT,
TokenType.LOOP, TokenType.AGAIN, TokenType.UNTIL, TokenType.UNLESS,
TokenType.FOREACH, TokenType.BUILD, TokenType.GIVE, TokenType.YES,
TokenType.NO, TokenType.EMPTY, TokenType.SHOW, TokenType.BLUEPRINT,
TokenType.SELF, TokenType.PARENT, TokenType.ALSO, TokenType.EITHER,
TokenType.AND, TokenType.OR, TokenType.NOT, TokenType.IS, TokenType.ISNT,
TokenType.BETWEEN, TokenType.CONTAINS, TokenType.LIKE, TokenType.BREAK,
TokenType.CONTINUE, TokenType.IMPORT, TokenType.EXPORT, TokenType.ATTEMPT,
TokenType.CATCH, TokenType.FINALLY, TokenType.THROW, TokenType.SWITCH,
TokenType.CASE, TokenType.DEFAULT, TokenType.INTERFACE, TokenType.ENUM,
TokenType.TYPE, TokenType.NAMESPACE, TokenType.MODULE, TokenType.VOID,
TokenType.ASYNC, TokenType.AWAIT, TokenType.TRY, TokenType.CLASS,
TokenType.FUNCTION, TokenType.LET, TokenType.CONST, TokenType.VAR,
TokenType.IF, TokenType.ELSE, TokenType.WHILE, TokenType.FOR,
TokenType.RETURN, TokenType.TRUE, TokenType.FALSE, TokenType.NULL,
TokenType.UNDEFINED, TokenType.THIS, TokenType.SUPER, TokenType.NEW,
TokenType.DELETE, TokenType.INSTANCEOF, TokenType.IN,
TokenType.OF, TokenType.STATIC, TokenType.PUBLIC, TokenType.PRIVATE,
TokenType.PROTECTED, TokenType.EXTENDS, TokenType.IMPLEMENTS,
TokenType.FROM, TokenType.AS, TokenType.WITH, TokenType.DO,
TokenType.GOTO, TokenType.LABEL, TokenType.YIELD, TokenType.GENERATOR,
TokenType.CONSOLE
];
return keywords.includes(this.type);
}
// Check if token is a literal
isLiteral() {
return [
TokenType.STRING, TokenType.NUMBER, TokenType.YES, TokenType.NO,
TokenType.TRUE, TokenType.FALSE, TokenType.EMPTY, TokenType.NULL,
TokenType.UNDEFINED
].includes(this.type);
}
// Check if token is an operator
isOperator() {
return [
TokenType.PLUS, TokenType.MINUS, TokenType.STAR, TokenType.SLASH,
TokenType.PERCENT, TokenType.EQUAL, TokenType.EQUAL_EQUAL,
TokenType.BANG_EQUAL, TokenType.GREATER, TokenType.GREATER_EQUAL,
TokenType.LESS, TokenType.LESS_EQUAL, TokenType.AND_AND, TokenType.OR_OR,
TokenType.ALSO, TokenType.EITHER, TokenType.IS, TokenType.ISNT,
TokenType.CONTAINS, TokenType.BETWEEN, TokenType.LIKE, TokenType.IN
].includes(this.type);
}
}
module.exports = { TokenType, Token };