petcarescript
Version:
PetCareScript - A modern, expressive programming language designed for humans
537 lines (481 loc) • 12.5 kB
JavaScript
/**
* PetCareScript AST (Abstract Syntax Tree)
* Node definitions for the abstract syntax tree
*/
// Base node with guaranteed accept method
class ASTNode {
accept(visitor) {
const methodName = `visit${this.constructor.name}`;
if (typeof visitor[methodName] === 'function') {
return visitor[methodName](this);
} else {
throw new Error(`Missing visitor method: ${methodName} in ${visitor.constructor.name}`);
}
}
}
// Main program
class ProgramNode extends ASTNode {
constructor(statements) {
super();
this.statements = statements || [];
}
}
// Declarations
class VariableDeclarationNode extends ASTNode {
constructor(name, initializer, type = null) {
super();
this.name = name;
this.initializer = initializer;
this.type = type;
}
}
class FunctionDeclarationNode extends ASTNode {
constructor(name, params, body, isAsync = false, returnType = null) {
super();
this.name = name;
this.params = params || [];
this.body = body || [];
this.isAsync = isAsync;
this.returnType = returnType;
}
}
class BlueprintDeclarationNode extends ASTNode {
constructor(name, parentBlueprint, methods, interfaces = []) {
super();
this.name = name;
this.parentBlueprint = parentBlueprint;
this.methods = methods || [];
this.interfaces = interfaces;
}
}
class ModuleDeclarationNode extends ASTNode {
constructor(name, exports) {
super();
this.name = name;
this.exports = exports || [];
}
}
class ImportDeclarationNode extends ASTNode {
constructor(specifiers, source, isDefault = false) {
super();
this.specifiers = specifiers || [];
this.source = source;
this.isDefault = isDefault;
}
}
class ExportDeclarationNode extends ASTNode {
constructor(declaration, specifiers = null, source = null, isDefault = false) {
super();
this.declaration = declaration;
this.specifiers = specifiers;
this.source = source;
this.isDefault = isDefault;
}
}
// Statements
class BlockStatementNode extends ASTNode {
constructor(statements) {
super();
this.statements = statements || [];
}
}
class ExpressionStatementNode extends ASTNode {
constructor(expression) {
super();
this.expression = expression;
}
}
class IfStatementNode extends ASTNode {
constructor(condition, thenBranch, elseBranch) {
super();
this.condition = condition;
this.thenBranch = thenBranch;
this.elseBranch = elseBranch;
}
}
class UnlessStatementNode extends ASTNode {
constructor(condition, thenBranch, elseBranch) {
super();
this.condition = condition;
this.thenBranch = thenBranch;
this.elseBranch = elseBranch;
}
}
class WhileStatementNode extends ASTNode {
constructor(condition, body, isUntil = false) {
super();
this.condition = condition;
this.body = body;
this.isUntil = isUntil;
}
}
class ForStatementNode extends ASTNode {
constructor(initializer, condition, increment, body) {
super();
this.initializer = initializer;
this.condition = condition;
this.increment = increment;
this.body = body;
}
}
class ForEachStatementNode extends ASTNode {
constructor(variable, iterable, body) {
super();
this.variable = variable;
this.iterable = iterable;
this.body = body;
}
}
class SwitchStatementNode extends ASTNode {
constructor(discriminant, cases) {
super();
this.discriminant = discriminant;
this.cases = cases || [];
}
}
class CaseClauseNode extends ASTNode {
constructor(test, consequent, isDefault = false) {
super();
this.test = test;
this.consequent = consequent || [];
this.isDefault = isDefault;
}
}
class ReturnStatementNode extends ASTNode {
constructor(keyword, value) {
super();
this.keyword = keyword;
this.value = value;
}
}
class PrintStatementNode extends ASTNode {
constructor(expression) {
super();
this.expression = expression;
}
}
class BreakStatementNode extends ASTNode {
constructor(label = null) {
super();
this.label = label;
}
}
class ContinueStatementNode extends ASTNode {
constructor(label = null) {
super();
this.label = label;
}
}
class ThrowStatementNode extends ASTNode {
constructor(expression) {
super();
this.expression = expression;
}
}
class TryStatementNode extends ASTNode {
constructor(tryBlock, catchBlock, catchVariable, finallyBlock) {
super();
this.tryBlock = tryBlock;
this.catchBlock = catchBlock;
this.catchVariable = catchVariable;
this.finallyBlock = finallyBlock;
}
}
// Testing nodes
class TestSuiteNode extends ASTNode {
constructor(name, body) {
super();
this.name = name;
this.body = body;
}
}
class TestCaseNode extends ASTNode {
constructor(name, body, isAsync = false) {
super();
this.name = name;
this.body = body;
this.isAsync = isAsync;
}
}
class AssertionNode extends ASTNode {
constructor(expression, message = null) {
super();
this.expression = expression;
this.message = message;
}
}
// HTTP/API nodes
class ServerDeclarationNode extends ASTNode {
constructor(name, port, routes) {
super();
this.name = name;
this.port = port;
this.routes = routes || [];
}
}
class RouteDeclarationNode extends ASTNode {
constructor(method, path, handler, middleware = []) {
super();
this.method = method;
this.path = path;
this.handler = handler;
this.middleware = middleware;
}
}
class MiddlewareDeclarationNode extends ASTNode {
constructor(name, handler) {
super();
this.name = name;
this.handler = handler;
}
}
// Database nodes
class DatabaseConnectionNode extends ASTNode {
constructor(name, connectionString, options = null) {
super();
this.name = name;
this.connectionString = connectionString;
this.options = options;
}
}
class QueryNode extends ASTNode {
constructor(type, target, fields = null, conditions = null, joins = null) {
super();
this.type = type; // select, insert, update, delete
this.target = target;
this.fields = fields;
this.conditions = conditions;
this.joins = joins;
}
}
class TransactionNode extends ASTNode {
constructor(body) {
super();
this.body = body;
}
}
// Expressions
class BinaryExpressionNode extends ASTNode {
constructor(left, operator, right) {
super();
this.left = left;
this.operator = operator;
this.right = right;
}
}
class UnaryExpressionNode extends ASTNode {
constructor(operator, right) {
super();
this.operator = operator;
this.right = right;
}
}
class CallExpressionNode extends ASTNode {
constructor(callee, args, isAsync = false) {
super();
this.callee = callee;
this.args = args || [];
this.isAsync = isAsync;
}
}
class MemberExpressionNode extends ASTNode {
constructor(object, property, computed = false, optional = false) {
super();
this.object = object;
this.property = property;
this.computed = computed;
this.optional = optional;
}
}
class AssignmentExpressionNode extends ASTNode {
constructor(name, value, operator = '=') {
super();
this.name = name;
this.value = value;
this.operator = operator;
}
}
class ConditionalExpressionNode extends ASTNode {
constructor(test, consequent, alternate) {
super();
this.test = test;
this.consequent = consequent;
this.alternate = alternate;
}
}
class AwaitExpressionNode extends ASTNode {
constructor(argument) {
super();
this.argument = argument;
}
}
class YieldExpressionNode extends ASTNode {
constructor(argument, delegate = false) {
super();
this.argument = argument;
this.delegate = delegate;
}
}
class LiteralNode extends ASTNode {
constructor(value, type = null) {
super();
this.value = value;
this.type = type;
}
}
class IdentifierNode extends ASTNode {
constructor(name) {
super();
this.name = name;
}
}
class ArrayExpressionNode extends ASTNode {
constructor(elements) {
super();
this.elements = elements || [];
}
}
class ObjectExpressionNode extends ASTNode {
constructor(properties) {
super();
this.properties = properties || [];
}
}
class TemplateStringNode extends ASTNode {
constructor(quasis, expressions) {
super();
this.quasis = quasis || [];
this.expressions = expressions || [];
}
}
class ArrowFunctionNode extends ASTNode {
constructor(params, body, isAsync = false) {
super();
this.params = params || [];
this.body = body;
this.isAsync = isAsync;
this.name = { lexeme: '<arrow>', type: 'IDENTIFIER' }; // Add name for compatibility
}
}
class SpreadElementNode extends ASTNode {
constructor(argument) {
super();
this.argument = argument;
}
}
class RestElementNode extends ASTNode {
constructor(argument) {
super();
this.argument = argument;
}
}
class DestructuringPatternNode extends ASTNode {
constructor(properties, isArray = false) {
super();
this.properties = properties || [];
this.isArray = isArray;
}
}
// Type nodes
class TypeAnnotationNode extends ASTNode {
constructor(typeAnnotation) {
super();
this.typeAnnotation = typeAnnotation;
}
}
class InterfaceDeclarationNode extends ASTNode {
constructor(name, body, extends_ = null) {
super();
this.name = name;
this.body = body || [];
this.extends = extends_;
}
}
class EnumDeclarationNode extends ASTNode {
constructor(name, members) {
super();
this.name = name;
this.members = members || [];
}
}
// Server/HTTP specific nodes
class ServerCallNode extends ASTNode {
constructor(variable, port) {
super();
this.variable = variable;
this.port = port;
}
}
class ServerMethodNode extends ASTNode {
constructor(server, method, path, handler) {
super();
this.server = server;
this.method = method;
this.path = path;
this.handler = handler;
}
}
class ServerListenNode extends ASTNode {
constructor(server, callback) {
super();
this.server = server;
this.callback = callback;
}
}
module.exports = {
ASTNode,
ProgramNode,
VariableDeclarationNode,
FunctionDeclarationNode,
BlueprintDeclarationNode,
ModuleDeclarationNode,
ImportDeclarationNode,
ExportDeclarationNode,
BlockStatementNode,
ExpressionStatementNode,
IfStatementNode,
UnlessStatementNode,
WhileStatementNode,
ForStatementNode,
ForEachStatementNode,
SwitchStatementNode,
CaseClauseNode,
ReturnStatementNode,
PrintStatementNode,
BreakStatementNode,
ContinueStatementNode,
ThrowStatementNode,
TryStatementNode,
TestSuiteNode,
TestCaseNode,
AssertionNode,
ServerDeclarationNode,
RouteDeclarationNode,
MiddlewareDeclarationNode,
DatabaseConnectionNode,
QueryNode,
TransactionNode,
BinaryExpressionNode,
UnaryExpressionNode,
CallExpressionNode,
MemberExpressionNode,
AssignmentExpressionNode,
ConditionalExpressionNode,
AwaitExpressionNode,
YieldExpressionNode,
LiteralNode,
IdentifierNode,
ArrayExpressionNode,
ObjectExpressionNode,
TemplateStringNode,
ArrowFunctionNode,
SpreadElementNode,
RestElementNode,
DestructuringPatternNode,
TypeAnnotationNode,
InterfaceDeclarationNode,
EnumDeclarationNode,
ServerCallNode,
ServerMethodNode,
ServerListenNode
};