Scripting and control environment for stage lighting
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

452 lines
8.6 KiB

/* ast.c */
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include "types.h"
#include "ast.h"
#include "mem.h"
extern int yylineno;
ast_list *make_list(ast *elem, ast_list *tail)
{
ast_list *list = safe_malloc(sizeof(ast_list));
list->elem = elem;
list->next = tail;
return list;
}
ast_list *reverse_list(ast_list *list)
{
ast_list *last = NULL;
ast_list *next;
while (list) {
next = list->next;
list->next = last;
last = list;
list = next;
}
return last;
}
ast *make_list_node(ast_list *list)
{
ast *elem = safe_malloc(sizeof(ast));
elem->tag = node_ast;
elem->info.node.tag = kind_list;
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_string(char *string)
{
ast *elem = safe_malloc(sizeof(ast));
elem->tag = str_ast;
elem->info.string = string;
elem->lineno = yylineno;
return elem;
}
ast *make_integer(long integer)
{
ast *elem = safe_malloc(sizeof(ast));
elem->tag = int_ast;
elem->info.integer = integer;
elem->lineno = yylineno;
return elem;
}
ast *make_real(float real)
{
ast *elem = safe_malloc(sizeof(ast));
elem->tag = real_ast;
elem->info.real = real;
elem->lineno = yylineno;
return elem;
}
ast *make_function(char *identifier, ast_list *args, ast_list *stmts)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list = NULL;
elem->tag = node_ast;
elem->info.node.tag = kind_fndef;
list = make_list(make_list_node(stmts), list);
list = make_list(make_list_node(args), list);
list = make_list(make_string(identifier), list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_fndefint(char *identifier, long num)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list = NULL;
elem->tag = node_ast;
elem->info.node.tag = kind_fndefint;
list = make_list(make_integer(num), list);
list = make_list(make_string(identifier), list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_fndefint_v(char *identifier, long num)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list = NULL;
elem->tag = node_ast;
elem->info.node.tag = kind_fndefint_v;
list = make_list(make_integer(num), list);
list = make_list(make_string(identifier), list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_constant(char *identifier, long num)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list = NULL;
elem->tag = node_ast;
elem->info.node.tag = kind_constant;
list = make_list(make_integer(num), list);
list = make_list(make_string(identifier), list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_realconstant(char *identifier, float num)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list = NULL;
elem->tag = node_ast;
elem->info.node.tag = kind_constant;
list = make_list(make_real(num), list);
list = make_list(make_string(identifier), list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_fndefext(char *identifier)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list = NULL;
elem->tag = node_ast;
elem->info.node.tag = kind_fndefext;
list = make_list(make_string(identifier), list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_variable(char *identifier)
{
ast *elem = safe_malloc(sizeof(ast));
elem->tag = var_ast;
elem->info.variable = identifier;
elem->lineno = yylineno;
return elem;
}
ast *make_array(char *identifier, ast *expression)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list;
elem->tag = array_ast;
elem->info.node.tag = kind_array;
list = make_list(expression, NULL);
list = make_list(make_variable(identifier), list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
/*
ast *make_assignment(char *identifier, ast *expression)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list;
elem->tag = node_ast;
elem->info.node.tag = kind_assign;
list = make_list(expression, NULL);
list = make_list(make_variable(identifier), list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
*/
ast *make_assignment(ast_list *identifier_list, ast *expression)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list;
elem->tag = node_ast;
elem->info.node.tag = kind_assign;
list = make_list(expression, NULL);
list = make_list(make_list_node(identifier_list), list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_binary_op(ast_kind op, ast *exp1, ast *exp2)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list;
elem->tag = node_ast;
elem->info.node.tag = op;
list = make_list(exp2, NULL);
list = make_list(exp1, list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_unary_op(ast_kind op, ast *exp1)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list;
elem->tag = node_ast;
elem->info.node.tag = op;
list = make_list(exp1, NULL);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_call(char *identifier, ast_list *args)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list;
elem->tag = node_ast;
elem->info.node.tag = kind_call;
list = make_list(make_list_node(args), NULL);
list = make_list(make_string(identifier), list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_statement(ast_kind type, ast *expression, ast_list *statements,
ast_list *more_statements)
{
ast *elem = safe_malloc(sizeof(ast));
ast_list *list;
elem->tag = node_ast;
elem->info.node.tag = type;
list = NULL;
if (more_statements)
list = make_list(make_list_node(more_statements), list);
list = make_list(make_list_node(statements), list);
list = make_list(expression, list);
elem->info.node.head = list;
elem->lineno = yylineno;
return elem;
}
ast *make_case_statement_variable(char *identifier)
{
ast *elem = safe_malloc(sizeof(ast));
elem->tag = casevar_ast;
elem->info.variable = identifier;
elem->lineno = yylineno;
return elem;
}
ast *make_case_statement_number(long num)
{
ast *elem = safe_malloc(sizeof(ast));
elem->tag = casenum_ast;
elem->info.integer = num;
elem->lineno = yylineno;
return elem;
}
ast *make_return_statement(ast *expression)
{
ast *elem = safe_malloc(sizeof(ast));
elem->tag = node_ast;
elem->info.node.tag = stmt_return;
elem->info.node.head = make_list(expression, NULL);
elem->lineno = yylineno;
return elem;
}
ast *make_break_statement(void)
{
ast *elem = safe_malloc(sizeof(ast));
elem->tag = node_ast;
elem->info.node.tag = stmt_break;
elem->info.node.head = NULL;
elem->lineno = yylineno;
return elem;
}
ast *make_default_statement(void)
{
ast *elem = safe_malloc(sizeof(ast));
elem->tag = node_ast;
elem->info.node.tag = stmt_default;
elem->info.node.head = NULL;
elem->lineno = yylineno;
return elem;
}
void indent(int spaces)
{
spaces = spaces * 2;
while (spaces--) {
printf(" ");
}
}
void ast_dump_main(ast *, int);
void ast_dump_list(ast_list *list, int spaces)
{
while (list) {
ast_dump_main(list->elem, spaces);
list = list->next;
}
}
void ast_dump_main(ast *node, int spaces)
{
indent(spaces);
switch (node->tag) {
case int_ast:
printf("integer: %ld\n", node->info.integer);
break;
case real_ast:
printf("real: %g\n", node->info.real);
break;
case var_ast:
printf("variable: %s\n", node->info.variable);
break;
case str_ast:
printf("string: %s\n", node->info.string);
break;
case node_ast:
switch (node->info.node.tag) {
case kind_fndef:
printf("function definition:\n");
break;
case kind_assign:
printf("assignment:\n");
break;
case kind_list:
printf("generic list:\n");
break;
case kind_call:
printf("function call:\n");
break;
case op_plus:
printf("plus operation:\n");
break;
case op_minus:
printf("minus operation:\n");
break;
case op_times:
printf("times operation:\n");
break;
case op_divide:
printf("divide operation:\n");
break;
case op_gt:
printf("greater than operation:\n");
break;
case op_lt:
printf("less than operation:\n");
break;
case op_ge:
printf("greater than or equal operation:\n");
break;
case op_le:
printf("less than or equal operation:\n");
break;
case op_eq:
printf("equality operation:\n");
break;
case op_ne:
printf("not equal operation:\n");
break;
case stmt_if:
printf("if statement:\n");
break;
case stmt_while:
printf("while statement:\n");
break;
default:
printf("unknown list type:\n");
break;
}
ast_dump_list(node->info.node.head, spaces+1);
break;
default:
printf("unknown node type\n");
break;
}
}
void ast_dump(ast *node)
{
ast_dump_main(node, 0);
}