/**
* Universidad de La Laguna
* Escuela Superior de Ingeniería y Tecnología
* Grado en Ingeniería Informática
* Procesadores de Lenguajes
*
* @author Juan Rodríguez Suárez
* @since Mar 04 2024
* @desc Contains all the functions to build the AST.
*/
const { $ } = require('./utils.js')
/**
* @brief Builds the root of the AST
* @param {object} child - The child node
* @returns {object} The root node
*/
function buildRoot(child) {
return {
type: 'Program',
body: [
{
type: 'ExpressionStatement',
expression: child,
}
],
sourceType: 'script'
};
}
/**
* @brief Builds a literal node
* @param {string} value - The value
* @returns {object} The literal node
*/
function buildLiteral(value) {
return {
type: 'Literal',
value,
raw: `\"${value}\"`
}
}
/**
* @brief Builds a call expression node
* @param {string} functionName - The function name
* @param {Array} args - The arguments
* @param {boolean} reservedWord - The reserved word
* @returns {object} The call expression node
*/
function buildCallExpression(functionName, args, reservedWord = false) {
return {
type: 'CallExpression',
callee: {
type: 'Identifier',
name: reservedWord ? functionName : $(functionName)
},
arguments: args
}
}
/**
* @brief Builds an identifier node
* @param {string} name - The name
* @returns {object} The identifier node
*/
function buildIdentifier(name) {
return {
type: 'Identifier',
name: name,
};
}
/**
* @brief Builds a variable declaration node
* @param {Array} declarations - The declarations
* @returns {object} The variable declaration node
*/
function buildVariableDeclaration(declarations) {
return {
type: 'VariableDeclaration',
declarations,
kind: 'let',
};
}
/**
* @brief Builds a variable declarator node
* @param {object} id - The id
* @returns {object} The variable declarator node
*/
function buildVariableDeclarator(id) {
return {
type: 'VariableDeclarator',
id: id,
init: null,
};
}
/**
* @brief Builds an assignment expression node
* @param {string} name - The name
* @param {string} operator - The operator
* @param {object} right - The right node
* @returns {object} The assignment expression node
*/
function buildAssignmentExpression(name, operator, right) {
return {
type: 'AssignmentExpression',
operator,
left: buildIdentifier(name),
right: right,
};
}
/**
* @brief Builds a sequence expression node
* @param {Array} expressions - The expressions
* @returns {object} The sequence expression node
*/
function buildSequenceExpression(expressions) {
return {
type: 'SequenceExpression',
expressions,
};
}
/**
* @brief Builds a member expression node
* @param {object} object - The object
* @param {string} operator - The operator
* @param {Array} args - The arguments
* @returns {object} The member expression node
*/
function buildMemberExpression(object, operator, args) {
return {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
object,
property: {
type: 'Identifier',
name: operator
}
},
arguments: args
};
}
/**
* @brief Builds a function declaration node
* @param {Array} params - The parameters
* @param {object} expression - The return expression
* @returns {object} The function declaration node
*/
function buildFunctionExpression(params, expression) {
return {
type: 'FunctionExpression',
id: null,
params,
body: {
type: 'BlockStatement',
body: [
{
type: 'ReturnStatement',
argument: expression
}
]
},
generator: false,
expression: false,
async: false
};
}
/**
* @brief Builds a logical expression node
* @param {object} left - The left node
* @param {string} operator - The operator
* @param {object} right - The right node
* @returns {object} The logical expression node
*/
function buildLogicalExpression(left, operator, right) {
return {
type: 'LogicalExpression',
operator,
left,
right
}
}
/**
* @brief Builds a unary expression node
* @param {string} operator - The operator
* @param {object} argument - The argument
* @param {boolean} prefix - The prefix
* @returns {object} The unary expression node
*/
function buildUnaryExpression(operator, argument, prefix) {
return {
type: 'UnaryExpression',
operator,
argument,
prefix
}
}
/**
* @brief Builds a sequence of calls to an identifier
* @param {string} id - The identifier
* @param {Array} calls - The calls
* @returns {object} The sequence of calls
*/
function buildIdCalls(id, calls) {
let node = id;
calls.forEach(ast => {
let parent = {
type: 'CallExpression',
callee: node,
arguments: ast
};
node = parent;
});
return node;
}
module.exports = {
buildRoot,
buildLiteral,
buildCallExpression,
buildIdentifier,
buildVariableDeclaration,
buildVariableDeclarator,
buildAssignmentExpression,
buildSequenceExpression,
buildMemberExpression,
buildFunctionExpression,
buildLogicalExpression,
buildUnaryExpression,
buildIdCalls
}