view src/ploki/match.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 "IO.h"
#include "Str.h"
#include "main_io.h"
#include "main_opt.h"
#include "match.h"
#include "re.h"
#include "run.h"
#include "val.h"

void do_match(struct val *v, t_regex *re) {
	size_t mstart, mend;
	size_t i;
	size_t bra;

	if (V_EXT_P(v)) {
		if (Opt.debug & DBG_REGEX) {
			V_STR(v);
			io_write_s(Err, "match: <<");
			io_write_m(Err, ko_ptr(v->ko), ko_length(v->ko));
			io_write_m(Err, "\n", 1);
		}

		if (!(io_bufred(v->magic.ext) && re_iomatch(re, v->magic.ext, &mstart, &mend))) {
			if (Opt.debug & DBG_REGEX) {
				io_write_s(Err, "...failed\n");
			}
			while (Interp.match.length) {
				--Interp.match.length;
				v_end(&Interp.match.matches[Interp.match.length]);
			}
			v->type = V_UNDEF;
			return;
		}

		if (Opt.debug & DBG_REGEX) {
			io_write_s(Err, "...success!\n");
		}
		v_set_n(&Interp.result, mend);

		bra = re_cabra(re);
		if (Interp.match.size < bra) {
			Interp.match.matches = xrealloc(Interp.match.matches, Interp.match.size = bra);
		}
		if (Interp.m_start.size < bra) {
			Interp.m_start.index = xrealloc(Interp.m_start.index, Interp.m_start.size = bra);
		}
		if (Interp.m_end.size < bra) {
			Interp.m_end.index = xrealloc(Interp.m_end.index, Interp.m_end.size = bra);
		}

		for (i = 0; i < bra; ++i) {
			size_t ms, me;

			if (re_backref(re, i, &ms, &me)) {
				if (i < Interp.match.length) {
					v_set_undef(&Interp.match.matches[i]);
				} else {
					v_init(&Interp.match.matches[Interp.match.length++]);
				}
				Interp.m_start.index[i] = -1;
				Interp.m_end.index[i] = -1;
			} else {
				if (i >= Interp.match.length) {
					v_init(&Interp.match.matches[Interp.match.length++]);
				}
				v_set_m(&Interp.match.matches[i], io_bufptr(v->magic.ext) + ms, me - ms);
				Interp.m_start.index[i] = ms;
				Interp.m_end.index[i] = me;
			}
		}

		io_read(v->magic.ext, NULL, mend);
		V_xxx_OFF(v);
	} else {
		String tmp;

		V_STR(v);
		V_xxx_OFF(v);

		St_fake(&tmp, (char *)ko_ptr(v->ko), ko_length(v->ko));

		if (Opt.debug & DBG_REGEX) {
			io_write_s(Err, "match: \"");
			io_write(Err, &tmp);
			io_write_s(Err, "\"\n");
		}

		if (!re_match(re, &tmp, &mstart, &mend)) {
			if (Opt.debug & DBG_REGEX) {
				io_write_s(Err, "...failed\n");
			}
			while (Interp.match.length) {
				--Interp.match.length;
				v_end(&Interp.match.matches[Interp.match.length]);
			}
			v->type = V_UNDEF;
			return;
		}

		if (Opt.debug & DBG_REGEX) {
			io_write_s(Err, "...success!\n");
		}
		v_set_n(&Interp.result, mend);

		bra = re_cabra(re);
		if (Interp.match.size < bra) {
			Interp.match.matches = xrealloc(Interp.match.matches, Interp.match.size = bra);
		}
		if (Interp.m_start.size < bra) {
			Interp.m_start.index = xrealloc(Interp.m_start.index, Interp.m_start.size = bra);
		}
		if (Interp.m_end.size < bra) {
			Interp.m_end.index = xrealloc(Interp.m_end.index, Interp.m_end.size = bra);
		}

		for (i = 0; i < bra; ++i) {
			size_t ms, me;

			if (re_backref(re, i, &ms, &me)) {
				if (i < Interp.match.length) {
					v_set_undef(&Interp.match.matches[i]);
				} else {
					v_init(&Interp.match.matches[Interp.match.length++]);
				}
				Interp.m_start.index[i] = -1;
				Interp.m_end.index[i] = -1;
			} else {
				if (i >= Interp.match.length) {
					v_init(&Interp.match.matches[Interp.match.length++]);
				}
				v_set_m(&Interp.match.matches[i], ko_ptr(v->ko) + ms, me - ms);
				Interp.m_start.index[i] = ms;
				Interp.m_end.index[i] = me;
			}
		}
	}

	if (!mstart) {
		ko_cpy_m(v->ko, "0.", 2);
		v->num = 0.0;
		v->type = V_STR_K | V_NUM_K;
		return;
	}

	v->num = mstart;
	v->type = V_NUM_K;
}