view lwasm/lwval.c @ 250:0986834ec7d3 2.x

Added no-op .bank pseudo-op to support compiling gcc6809
author lost
date Thu, 26 Nov 2009 21:12:45 +0000
parents bae1e3ecdce1
children
line wrap: on
line source

/*
lwval.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 implementations associated with the expression evaluator
used by LWASM.

*/
#include <config.h>

#include <malloc.h>

#define __lwval_c_seen__
#include "lwval.h"

LWVAL *lwval_construct_int(int value)
{
	LWVAL *v;
	
	v = malloc(sizeof(LWVAL));
	if (!v)
		return NULL;
	
	v -> lwval_type = LWVAL_TYPE_INT;
	v -> dt.lwval_int = value;
	
	return v;
}

LWVAL *lwval_construct_err(int errno)
{
	LWVAL *v;
	
	v = malloc(sizeof(LWVAL));
	if (!v)
		return NULL;
	
	v -> lwval_type = LWVAL_TYPE_ERR;
	v -> dt.lwval_int = errno;
	
	return v;
}

LWVAL *lwval_construct_nan(void)
{
	LWVAL *v;
	
	v = malloc(sizeof(LWVAL));
	if (!v)
		return NULL;
	
	v -> lwval_type = LWVAL_TYPE_NAN;
	
	return v;
}

LWVAL *lwval_construct_undef(void)
{
	LWVAL *v;
	
	v = malloc(sizeof(LWVAL));
	if (!v)
		return NULL;
	
	v -> lwval_type = LWVAL_TYPE_UNDEF;
	
	return v;
}

LWVAL *lwval_construct_expr(LWVAL *v1, LWVAL *v2, int op)
{
	LWVAL *v;
	v = malloc(sizeof(LWVAL));
	if (!v)
		return NULL;
	
	v -> lwval_type = LWVAL_TYPE_EXPR;
	v -> dt.expr.v1 = v1;
	v -> dt.expr.v2 = v2;
	v -> dt.expr.op = op;
	return v;
}

void lwval_destroy(LWVAL *value)
{
	if (value)
	{
		lwval_clear(value);
		free(value);
	}
}

// performs a deep copy of an LWVAL, including ALL referenced values
void lwval_dup(LWVAL *v1, LWVAL *v2)
{
	lwval_clear(v2);
	
	switch (v1 -> lwval_type)
	{
	case LWVAL_TYPE_INT:
	case LWVAL_TYPE_ERR:
		v2 -> dt.lwval_int = v1 -> dt.lwval_int;
		break;
	
	case LWVAL_TYPE_EXPR:
		v2 -> dt.expr.op = v1 -> dt.expr.op;
		if (v1 -> dt.expr.v1)
		{
			v2 -> dt.expr.v1 = lwval_construct_undef();
			lwval_dup(v1 -> dt.expr.v1, v2 -> dt.expr.v1);
		}
		else
			v2 -> dt.expr.v1 = NULL;
		if (v1 -> dt.expr.v2)
		{
			v2 -> dt.expr.v2 = lwval_construct_undef();
			lwval_dup(v1 -> dt.expr.v2, v2 -> dt.expr.v2);
		}
		else
			v2 -> dt.expr.v2 = NULL;
		break;
	}
	
	v2 -> lwval_type = v1 -> lwval_type;
}

void lwval_clear(LWVAL *value)
{
	switch (value -> lwval_type)
	{
	case LWVAL_TYPE_EXPR:
		lwval_destroy(value -> dt.expr.v1);
		lwval_destroy(value -> dt.expr.v2);
		break;
	}
	value -> lwval_type = LWVAL_TYPE_UNDEF;
}

// for integer, simply negate value
// for expr, change to "-1 * (expr)"
// everything else: error
LWVAL *lwval_neg(LWVAL *v1)
{
	switch (v1 -> lwval_type)
	{
	case LWVAL_TYPE_INT:
		v1 -> dt.lwval_int = -(v1 -> dt.lwval_int);
		break;
	
	case LWVAL_TYPE_EXPR:
		{
			LWVAL *v, *v2;
			v = lwval_construct_undef();
			lwval_dup(v1, v);
			lwval_clear(v1);
			v2 = lwval_construct_expr(lwval_construct_int(-1), v, '*');
			lwval_dup(v2, v1);
			lwval_destroy(v2);
		}
		break;
	
	default:
		lwval_clear(v1);
		v1 -> lwval_type = LWVAL_TYPE_ERR;
		v1 -> dt.lwval_int = 1;
	}
	
	return v1;
}

// v1 + v2 -> v1
LWVAL *lwval_add(LWVAL *v1, LWVAL *v2)
{
}

// v1 - v2 -> v1
LWVAL *lwval_sub(LWVAL *v1, LWVAL *v2)
{
}

// v1 * v2 -> v1
LWVAL *lwval_mul(LWVAL *v1, LWVAL *v2)
{
}

// v1 / v2 -> v1
LWVAL *lwval_div(LWVAL *v1, LWVAL *v2)
{
}

// v1 % v2 -> v1
LWVAL *lwval_mod(LWVAL *v1, LWVAL *v2)
{
}