#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: gsp_act.c,v 1.6 2025/11/24 08:04:28 nia Exp $");
#endif
#include <stdlib.h>
#include <string.h>
#include <util.h>
#include "gsp_ass.h"
void
free_operands(operand l)
{
operand op, oq;
for( op = l; op != NULL; op = oq ){
oq = op->next;
if( op->type == EXPR ||
(op->type == EA && op->mode >= M_INDEX) )
free_expr(op->op_u.value);
free(op);
}
}
operand
add_operand(operand first, operand last)
{
operand p;
for( p = first; p->next != NULL; p = p->next )
;
p->next = last;
return first;
}
operand
reg_op(int reg)
{
operand o;
new(o);
o->type = REG;
o->reg_no = reg;
o->next = NULL;
return o;
}
operand
expr_op(expr val)
{
operand o;
new(o);
o->type = EXPR;
o->op_u.value = val;
o->next = NULL;
return o;
}
operand
string_op(char *str)
{
operand o;
new(o);
o->type = STR_OPN;
o->op_u.string = str;
o->next = NULL;
return o;
}
operand
abs_adr(expr adr)
{
operand o;
new(o);
o->type = EA;
o->mode = M_ABSOLUTE;
o->op_u.value = adr;
o->next = NULL;
return o;
}
operand
reg_ind(int reg, int mode)
{
operand o;
new(o);
o->type = EA;
o->mode = mode;
o->reg_no = reg;
o->next = NULL;
return o;
}
operand
reg_indxy(int reg, char *xy)
{
ucasify(xy);
if( strcmp(xy, ".XY") != 0 )
perr("Register format must be .XY");
return reg_ind(reg, M_INDXY);
}
operand
reg_index(int reg, expr disp)
{
operand o;
o = reg_ind(reg, M_INDEX);
o->op_u.value = disp;
return o;
}
expr
id_expr(char *id)
{
expr x;
new(x);
x->e_op = SYM;
x->e_sym = lookup(id, TRUE);
return x;
}
expr
num_expr(int val)
{
expr x;
new(x);
x->e_op = CONST;
x->e_val = val;
return x;
}
expr
here_expr()
{
expr x;
new(x);
x->e_op = '.';
return x;
}
expr
bexpr(int op, expr l, expr r)
{
expr x;
new(x);
x->e_op = op;
x->e_left = l;
x->e_right = r;
return x;
}
void
free_expr(expr x)
{
if( x->e_op != SYM && x->e_op != CONST && x->e_op != '.' ){
free_expr(x->e_left);
if( x->e_right != NULL )
free_expr(x->e_right);
}
free(x);
}