Can “new Function()” be safe?

I understand that it’s risky to consider this when it comes to security. However I am currently planning a project with the following ambitions:

Create a grammar using Nearley.js.

Use that grammar to store a function in my database for example:

"IF(G.cells[id]!=NULL){INVALIDMOVE}, playerID->G.cells[id]"

That function gets translated in the following parser in the following way:

function translateAST(ast) {
  switch (ast.type) {
    case 'condition':
      return `
        if (${translateExpr(ast.condition)}) {
          return ${translateAction(ast.action)};
        }
      `;
    case 'assignment':
      return `
        ${ast.target} = ${translateExpr(ast.value)};
      `;
    default:
      throw new Error(`Unknown AST node type: ${ast.type}`);
  }
}

function translateExpr(expr) {
  switch (expr.type) {
    case 'notEqual':
      return `${expr.left} !== ${expr.right}`;
    case 'identifier':
      return expr.name;
    default:
      throw new Error(`Unknown expression type: ${expr.type}`);
  }
}

function translateAction(action) {
  switch (action.type) {
    case 'action':
      if (action.name === 'INVALID_MOVE') {
        return 'INVALID_MOVE';
      }
    default:
      throw new Error(`Unknown action type: ${action.type}`);
  }
}

Then after we have parsed this

function generateMoveFunction(code) {
  return function({ G, playerID }, id) {
    // Use a closure to safely execute the code
    const func = new Function('G', 'playerID', 'id', `
      ${code}
    `);
    return func(G, playerID, id);
  };
}


// Example usage
const moveString = "IF(G.cells[id]!=NULL){INVALIDMOVE}, playerID->G.cells[id]";
const ast = parseMove(moveString);
const code = translateAST(ast);
const moveFunction = generateMoveFunction(code);

Then pass this moveFunction as a move for a library

const moves = {
  clickCell: moveFunction,
};

// Boardgame.io game configuration
const MyGame = {
  setup: () => ({ cells: Array(9).fill(null) }),
  moves: moves,
};

Is this a bad idea?