view src/ploki/sub.c @ 12292:d51f2100210c draft

<kspalaiologos> `` cat <<<"asmbf && bfi output.b" > /hackenv/ibin/asmbf
author HackEso <hackeso@esolangs.org>
date Thu, 02 Jan 2020 15:38:21 +0000
parents ac0403686959
children
line wrap: on
line source

#include "expr.h"
#include "main_opt.h"
#include "sub.h"
#include "transmogrify.h"
#include "xmalloc.h"

#include <stddef.h>

struct sub {
	struct expr *expr;
	size_t refs;
	size_t id;
};

static struct expr *dup(const struct expr *e) {
	struct expr *p;

	if (!e) {
		return NULL;
	}

	p = xmalloc(1, sizeof *p);
	*p = *e;

	switch (e->type) {
		case literE:
			p->v.val = v_undef();
			v_set(p->v.val, e->v.val);
			break;

		case varE:
			break;

		case varhashE:
			p->right = dup(e->right);
			break;

		case symbolE:
			switch (e->op) {
				case S_ARGV:
					p->right = dup(e->right);
					break;
			}
			break;

		case unopE:
			p->right = dup(e->right);
			if (e->op == F_MATCH) {
				p->left.rx = re_dup(e->left.rx);
			}
			break;

		case binopE:
		case listE:
			p->right = dup(e->right);
			p->left.expr = dup(e->left.expr);
			break;
	}

	return p;
}

static void solid(struct expr *e) {
	if (!e) {
		return;
	}

	switch (e->type) {
		case literE:
			break;

		case varE:
			e->v.val = eval_expr(e);
			e->type = literE;
			break;

		case varhashE:
			break;

		case symbolE:
			switch (e->op) {
				case S_ARGV:
					solid(e->right);
					break;
			}
			break;

		case unopE:
			solid(e->right);
			break;

		case binopE:
		case listE:
			solid(e->left.expr);
			solid(e->right);
			break;
	}
}

struct sub *sub_new(const struct expr *e) {
	static size_t idcount;
	struct sub *p;
	p = xmalloc(1, sizeof *p);
	p->expr = dup(e);
	solid(p->expr);
	if (!Opt.unoptimize) {
		trans_fold(&p->expr);
	}
	p->refs = 0;
	p->id = idcount++;
	return p;
}

struct sub *sub_incr(struct sub *p) {
	++p->refs;
	return p;
}

void sub_decr(struct sub *p) {
	if (!p->refs) {
		free_expr(p->expr);
		xfree(p);
		return;
	}
	--p->refs;
}

struct expr *sub_expr(const struct sub *p) {
	return p->expr;
}

size_t sub_id(const struct sub *p) {
	return p->id;
}