miller/c/dsls/ex_ast.c
2016-11-06 14:24:44 -05:00

232 lines
11 KiB
C

#include <string.h>
#include "../lib/mlrutil.h"
#include "ex_ast.h"
// ----------------------------------------------------------------
ex_ast_t* ex_ast_alloc() {
ex_ast_t* past = mlr_malloc_or_die(sizeof(ex_ast_t));
past->proot = NULL;
return past;
}
// ----------------------------------------------------------------
ex_ast_node_t* ex_ast_node_alloc(char* text, ex_ast_node_type_t type) {
ex_ast_node_t* pnode = (ex_ast_node_t*)mlr_malloc_or_die(
sizeof(ex_ast_node_t));
pnode->text = mlr_strdup_or_die(text);
pnode->type = type;
pnode->pchildren = NULL;
return pnode;
}
// ----------------------------------------------------------------
ex_ast_node_t* ex_ast_node_copy(ex_ast_node_t* pother) {
ex_ast_node_t* pnode = ex_ast_node_alloc(pother->text, pother->type);
return pnode;
}
// ----------------------------------------------------------------
ex_ast_node_t* ex_ast_tree_copy(ex_ast_node_t* pold) {
ex_ast_node_t* pnew = ex_ast_node_copy(pold);
if (pold->pchildren != NULL) {
pnew->pchildren = sllv_alloc();
for (sllve_t* pe = pold->pchildren->phead; pe != NULL; pe = pe->pnext) {
ex_ast_node_t* pchild = pe->pvvalue;
sllv_append(pnew->pchildren, ex_ast_tree_copy(pchild));
}
}
return pnew;
}
// ----------------------------------------------------------------
ex_ast_node_t* ex_ast_node_alloc_zary(char* text, ex_ast_node_type_t type)
{
ex_ast_node_t* pnode = ex_ast_node_alloc(text, type);
pnode->pchildren = sllv_alloc();
return pnode;
}
// ----------------------------------------------------------------
ex_ast_node_t* ex_ast_node_alloc_unary(char* text, ex_ast_node_type_t type,
ex_ast_node_t* pa)
{
ex_ast_node_t* pnode = ex_ast_node_alloc(text, type);
pnode->pchildren = sllv_alloc();
sllv_append(pnode->pchildren, pa);
return pnode;
}
// ----------------------------------------------------------------
ex_ast_node_t* ex_ast_node_alloc_binary(char* text, ex_ast_node_type_t type,
ex_ast_node_t* pa, ex_ast_node_t* pb)
{
ex_ast_node_t* pnode = ex_ast_node_alloc(text, type);
pnode->pchildren = sllv_alloc();
sllv_append(pnode->pchildren, pa);
sllv_append(pnode->pchildren, pb);
return pnode;
}
// ----------------------------------------------------------------
ex_ast_node_t* ex_ast_node_alloc_ternary(char* text, ex_ast_node_type_t type,
ex_ast_node_t* pa, ex_ast_node_t* pb, ex_ast_node_t* pc)
{
ex_ast_node_t* pnode = ex_ast_node_alloc(text, type);
pnode->pchildren = sllv_alloc();
sllv_append(pnode->pchildren, pa);
sllv_append(pnode->pchildren, pb);
sllv_append(pnode->pchildren, pc);
return pnode;
}
// ----------------------------------------------------------------
ex_ast_node_t* ex_ast_node_prepend_arg(
ex_ast_node_t* pa, ex_ast_node_t* pb)
{
if (pa->pchildren == NULL)
pa->pchildren = sllv_alloc();
sllv_push(pa->pchildren, pb);
return pa;
}
ex_ast_node_t* ex_ast_node_append_arg(
ex_ast_node_t* pa, ex_ast_node_t* pb)
{
if (pa->pchildren == NULL)
pa->pchildren = sllv_alloc();
sllv_append(pa->pchildren, pb);
return pa;
}
ex_ast_node_t* ex_ast_node_set_function_name(
ex_ast_node_t* pa, char* name)
{
free(pa->text);
pa->text = mlr_strdup_or_die(name);
return pa;
}
// ----------------------------------------------------------------
void ex_ast_print(ex_ast_t* past) {
printf("AST ROOT:\n");
if (past->proot == NULL) {
printf("(null)\n");
} else {
ex_ast_node_print(past->proot);
}
}
// ----------------------------------------------------------------
static void ex_ast_node_print_aux(ex_ast_node_t* pnode, int level, FILE* o) {
if (pnode == NULL)
return;
for (int i = 0; i < level; i++)
fprintf(o, " ");
fprintf(o, "text=\"%s\", type=%s%s\n",
pnode->text,
ex_ast_node_describe_type(pnode->type),
(pnode->pchildren != NULL) ? ":" : ".");
if (pnode->pchildren != NULL) {
for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) {
ex_ast_node_print_aux(pe->pvvalue, level + 1, o);
}
}
}
void ex_ast_node_print(ex_ast_node_t* pnode) {
ex_ast_node_print_aux(pnode, 0, stdout);
}
void ex_ast_node_fprint(ex_ast_node_t* pnode, FILE* o) {
ex_ast_node_print_aux(pnode, 0, o);
}
// ----------------------------------------------------------------
char* ex_ast_node_describe_type(ex_ast_node_type_t type) {
switch(type) {
case MD_AST_NODE_TYPE_STATEMENT_BLOCK: return "statement_list"; break;
case MD_AST_NODE_TYPE_BEGIN: return "begin"; break;
case MD_AST_NODE_TYPE_END: return "end"; break;
case MD_AST_NODE_TYPE_STRING_LITERAL: return "string_literal"; break;
case MD_AST_NODE_TYPE_NUMERIC_LITERAL: return "numeric_literal"; break;
case MD_AST_NODE_TYPE_BOOLEAN_LITERAL: return "boolean_literal"; break;
case MD_AST_NODE_TYPE_REGEXI: return "regexi"; break;
case MD_AST_NODE_TYPE_FIELD_NAME: return "field_name"; break;
case MD_AST_NODE_TYPE_INDIRECT_FIELD_NAME: return "indirect_field_name"; break;
case MD_AST_NODE_TYPE_FULL_SREC: return "full_srec"; break;
case MD_AST_NODE_TYPE_OOSVAR_KEYLIST: return "oosvar_keylist"; break;
case MD_AST_NODE_TYPE_FULL_OOSVAR: return "full_oosvar"; break;
case MD_AST_NODE_TYPE_NON_SIGIL_NAME: return "non_sigil_name"; break;
case MD_AST_NODE_TYPE_OPERATOR: return "operator"; break;
case MD_AST_NODE_TYPE_SREC_ASSIGNMENT: return "srec_assignment"; break;
case MD_AST_NODE_TYPE_INDIRECT_SREC_ASSIGNMENT: return "indirect_srec_assignment"; break;
case MD_AST_NODE_TYPE_OOSVAR_ASSIGNMENT: return "oosvar_assignment"; break;
case MD_AST_NODE_TYPE_OOSVAR_FROM_FULL_SREC_ASSIGNMENT: return "oosvar_from_full_srec_assignment"; break;
case MD_AST_NODE_TYPE_FULL_SREC_FROM_OOSVAR_ASSIGNMENT: return "full_srec_from_oosvar_assignment"; break;
case MD_AST_NODE_TYPE_CONTEXT_VARIABLE: return "context_variable"; break;
case MD_AST_NODE_TYPE_STRIPPED_AWAY: return "stripped_away"; break;
case MD_AST_NODE_TYPE_CONDITIONAL_BLOCK: return "conditional_block"; break;
case MD_AST_NODE_TYPE_FILTER: return "filter"; break;
case MD_AST_NODE_TYPE_UNSET: return "unset"; break;
case MD_AST_NODE_TYPE_EMITF: return "emitf"; break;
case MD_AST_NODE_TYPE_EMITF_WRITE: return "emitf_write"; break;
case MD_AST_NODE_TYPE_EMITF_APPEND: return "emitf_append"; break;
case MD_AST_NODE_TYPE_EMITP: return "emitp"; break;
case MD_AST_NODE_TYPE_EMITP_WRITE: return "emitp_write"; break;
case MD_AST_NODE_TYPE_EMITP_APPEND: return "emitp_append"; break;
case MD_AST_NODE_TYPE_EMIT: return "emit"; break;
case MD_AST_NODE_TYPE_EMIT_WRITE: return "emit_write"; break;
case MD_AST_NODE_TYPE_EMIT_APPEND: return "emit_append"; break;
case MD_AST_NODE_TYPE_EMITP_LASHED: return "emitp_lashed"; break;
case MD_AST_NODE_TYPE_EMITP_LASHED_WRITE: return "emitp_lashed_write"; break;
case MD_AST_NODE_TYPE_EMITP_LASHED_APPEND: return "emitp_lashed_append"; break;
case MD_AST_NODE_TYPE_EMIT_LASHED: return "emit_lashed"; break;
case MD_AST_NODE_TYPE_EMIT_LASHED_WRITE: return "emit_lashed_write"; break;
case MD_AST_NODE_TYPE_EMIT_LASHED_APPEND: return "emit_lashed_append"; break;
case MD_AST_NODE_TYPE_DUMP: return "dump"; break;
case MD_AST_NODE_TYPE_DUMP_WRITE: return "dump_write"; break;
case MD_AST_NODE_TYPE_DUMP_APPEND: return "dump_append"; break;
case MD_AST_NODE_TYPE_EDUMP: return "edump"; break;
case MD_AST_NODE_TYPE_PRINT: return "print"; break;
case MD_AST_NODE_TYPE_PRINT_WRITE: return "print_write"; break;
case MD_AST_NODE_TYPE_PRINT_APPEND: return "print_append"; break;
case MD_AST_NODE_TYPE_PRINTN: return "printn"; break;
case MD_AST_NODE_TYPE_PRINTN_WRITE: return "printn_write"; break;
case MD_AST_NODE_TYPE_PRINTN_APPEND: return "printn_append"; break;
case MD_AST_NODE_TYPE_EPRINT: return "eprint"; break;
case MD_AST_NODE_TYPE_EPRINTN: return "eprintn"; break;
case MD_AST_NODE_TYPE_ALL: return "all"; break;
case MD_AST_NODE_TYPE_ENV: return "env"; break;
case MD_AST_NODE_TYPE_WHILE: return "while"; break;
case MD_AST_NODE_TYPE_DO_WHILE: return "do_while"; break;
case MD_AST_NODE_TYPE_FOR_SREC: return "for_srec"; break;
case MD_AST_NODE_TYPE_FOR_OOSVAR: return "for_oosvar"; break;
case MD_AST_NODE_TYPE_FOR_VARIABLES: return "for_variables"; break;
case MD_AST_NODE_TYPE_NONINDEXED_LOCAL_VARIABLE: return "local_variable"; break;
case MD_AST_NODE_TYPE_IN: return "in"; break;
case MD_AST_NODE_TYPE_BREAK: return "break"; break;
case MD_AST_NODE_TYPE_CONTINUE: return "continue"; break;
case MD_AST_NODE_TYPE_IF_HEAD: return "if_head"; break;
case MD_AST_NODE_TYPE_IF_ITEM: return "if_item"; break;
default: return "???";
}
}
// ----------------------------------------------------------------
void ex_ast_free(ex_ast_t* past) {
ex_ast_node_free(past->proot);
free(past);
}
// ----------------------------------------------------------------
void ex_ast_node_free(ex_ast_node_t* pnode) {
if (pnode->pchildren) {
for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) {
ex_ast_node_t* pchild = pe->pvvalue;
ex_ast_node_free(pchild);
}
sllv_free(pnode->pchildren);
}
free(pnode->text);
free(pnode);
}