view src/expr.c @ 17:df0c4a46af8f

Started adding expression handling infrastructure
author lost
date Thu, 01 Jan 2009 02:26:26 +0000
parents 1f598d89b9b0
children 218aabbc3b1a
line wrap: on
line source

/*
expr.c
Copyright © 2008 William Astle

This file is part of LWASM.

LWASM is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
*/

/*
This file contains the actual expression evaluator which uses the LWVAL
mechanism to store results.
*/

#define __expr_c_seen__

#include <stdio.h>
#include <stdlib.h>

#include "expr.h"
#include "util.h"

lwasm_expr_stack_t *lwasm_expr_stack_create(void)
{
	lwasm_expr_stack_t *s;
	
	s = lwasm_alloc(sizeof(lwasm_expr_stack_t));
	s -> head = NULL;
	s -> tail = NULL;
	return s;
}

void lwasm_expr_stack_free(lwasm_expr_stack_t *s)
{
	while (s -> head)
	{
		s -> tail = s -> head;
		s -> head = s -> head -> next;
		lwasm_expr_term_free(s -> tail -> term);
		lwasm_free(s -> tail);
	}
	lwasm_free(s);
}

void lwasm_expr_term_free(lwasm_expr_term_t *t)
{
	if (t)
	{
		if (t -> symbol)
			lwasm_free(t -> symbol);
		lwasm_free(t);
	}
}

lwasm_expr_term_t *lwasm_expr_term_create_oper(int oper)
{
	lwasm_expr_term_t *t;
	
	t = lwasm_alloc(sizeof(lwasm_expr_term_t));
	t -> term_type = LWASM_TERM_OPER;
	t -> value = oper;
	return t;
}

lwasm_expr_term_t *lwasm_expr_term_create_int(int val)
{
	lwasm_expr_term_t *t;
	
	t = lwasm_alloc(sizeof(lwasm_expr_term_t));
	t -> term_type = LWASM_TERM_INT;
	t -> value = val;
	return t;
}

lwasm_expr_term_t *lwasm_expr_term_create_sym(char *sym)
{
	lwasm_expr_term_t *t;
	
	t = lwasm_alloc(sizeof(lwasm_expr_term_t));
	t -> term_type = LWASM_TERM_SYM;
	t -> symbol = lwasm_strdup(sym);
	return t;
}

lwasm_expr_term_t *lwasm_expr_term_dup(lwasm_expr_term_t *t)
{
	switch (t -> term_type)
	{
	case LWASM_TERM_INT:
		return lwasm_expr_term_create_int(t -> value);
		
	case LWASM_TERM_OPER:
		return lwasm_expr_term_create_oper(t -> value);
		
	case LWASM_TERM_SYM:
		return lwasm_expr_term_create_sym(t -> symbol);
		
	default:
		fprintf(stderr, "lwasm_expr_term_dup(): invalid term type %d\n", t -> term_type);
		exit(1);
	}
// can't get here
}

void lwasm_expr_stack_push(lwasm_expr_stack_t *s, lwasm_expr_term_t *t)
{
	lwasm_expr_stack_node_t *n;

	if (!s)
	{
		fprintf(stderr, "lwasm_expr_stack_push(): invalid stack pointer\n");
		exit(1);
	}
	
	n = lwasm_alloc(sizeof(lwasm_expr_stack_node_t));
	n -> next = NULL;
	n -> prev = s -> tail;
	n -> term = lwasm_expr_term_dup(t);
	
	if (s -> head)
	{
		s -> tail -> next = n;
		s -> tail = n;
	}
	else
	{
		s -> head = n;
		s -> tail = n;
	}
}

lwasm_expr_term_t *lwasm_expr_stack_pop(lwasm_expr_stack_t *s)
{
	lwasm_expr_term_t *t;
	lwasm_expr_stack_node_t *n;
	
	if (!(s -> tail))
		return NULL;
	
	n = s -> tail;
	s -> tail = n -> prev;
	if (!(n -> prev))
	{
		s -> head = NULL;
	}
	
	t = n -> term;
	n -> term = NULL;
	
	lwasm_free(n);
	
	return t;
}