view src/ploki/sub.c @ 8916:0234daffd946

<oerjan> addquote <int-e> I couldn\'t help thinking that maybe if one considers the ramifications in full detail it will turn out that overthinking is often not helpful and therefore, not something to be proud of.
author HackBot
date Sun, 14 Aug 2016 02:31:47 +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;
}