Exemplo n.º 1
0
/*======================================+
 * llrpt_newfile -- Switch output to new file
 * usage: newfile(STRING, BOOL) -> VOID
 *=====================================*/
PVALUE
llrpt_newfile (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	PNODE argvar = builtin_args(node);
	BOOLEAN aflag=FALSE;
	STRING name=0;
	PVALUE val = eval_and_coerce(PSTRING, argvar, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonstrx, "newfile", "1");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	name = pvalue_to_string(val);
	if (!name || !name[0]) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, "1st arg to newfile must be a nonempty string.");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	strupdate(&outfilename, name);
	delete_pvalue_ptr(&val);
	val = eval_and_coerce(PBOOL, argvar=inext(argvar), stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonboox, "newfile", "2");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	aflag = pvalue_to_bool(val);
	delete_pvalue_ptr(&val);
	if (!set_output_file(outfilename, aflag)) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, NULL, "Failed to open output file: %s", outfilename);
	}
	return NULL;
}
Exemplo n.º 2
0
/*===============================================+
 * llrpt_difference -- Create difference of two INDISEQs
 * usage: difference(SET, SET) -> SET
 *==============================================*/
PVALUE
llrpt_difference (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	PNODE arg1 = builtin_args(node);
	PNODE arg2 = inext(arg1);
	INDISEQ op2=0, op1=0;
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	PVALUE val2=0;
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonsetx, "difference", "1");
		return NULL;
	}
	/* NULL indiseqs are possible, because of getindiset */
	op1 = pvalue_to_seq(val1);
	val2 = eval_and_coerce(PSET, arg2, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg2, val2, nonsetx, "difference", "2");
		return NULL;
	}
	op2 = pvalue_to_seq(val2);
	/* do actual difference */
	op2 = difference_indiseq(op1, op2);
	set_pvalue_seq(val1, op2);
	/* delay to last minute lest it is a temp owning seq,
	eg, difference(ancestorset(i),ancestorset(j)) */
	delete_pvalue(val2);
	return val1;
}
Exemplo n.º 3
0
/*========================================+
 * llrpt_row -- Position output to start of row
 * usage: row(INT) -> VOID
 *=======================================*/
PVALUE
llrpt_row (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INT row=0;
	PNODE argvar = builtin_args(node);
	PVALUE val = eval_and_coerce(PINT, argvar, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonint1, "row");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	*eflg = TRUE;
	row = pvalue_to_int(val);
	delete_pvalue_ptr(&val);
	if (outputmode != PAGEMODE) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, "row only valid in page mode");
		return NULL;
	}
	if (row < 1 || row > __rows) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, badarg1, "row");
		return NULL;
	}
	*eflg = FALSE;
	currow = row;
	curcol = 1;
	return NULL;
}
Exemplo n.º 4
0
/*====================================================+
 * llrpt_descendentset -- Create descendent set of an INDISEQ
 * usage: descendantset(SET) -> SET
 *===================================================*/
PVALUE
llrpt_descendentset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "descendentset");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	seq = descendent_indiseq(seq);
	set_pvalue_seq(val1, seq);
	return val1;
}
Exemplo n.º 5
0
/*==========================================+
 * llrpt_childset -- Create child set of an INDISEQ
 * usage: childset(SET) -> SET
 *=========================================*/
PVALUE
llrpt_childset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "childset");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	/* do actual construction of child set */
	seq = child_indiseq(seq);
	set_pvalue_seq(val1, seq);
	return val1;
}
Exemplo n.º 6
0
/*===================================================+
 * llrpt_gengedcomstrong -- Generate GEDCOM output from an INDISEQ
 * usage: gengedcom(SET) -> VOID
 * Perry 2000/11/03
 *==================================================*/
PVALUE
llrpt_gengedcomstrong (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "gengedcomstrong");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	gen_gedcom(seq, GENGEDCOM_STRONG_DUMP, eflg);
	/* delay to last minute lest it is a temp owning seq,
	eg, gengedcom(ancestorset(i)) */
	delete_pvalue(val1);
	return NULL;
}
Exemplo n.º 7
0
/*=========================================+
 * llrpt_parentset -- Create parent set of INDISEQ
 * usage: parentset(SET) -> SET
 *========================================*/
PVALUE
llrpt_parentset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "parentset");
		return NULL;
	}
	/* NULL indiseqs are possible, because of getindiset */
	seq = pvalue_to_seq(val1);
	/* do actual construction of parent set */
	seq = parent_indiseq(seq);
	set_pvalue_seq(val1, seq);
	return val1;
}
Exemplo n.º 8
0
/*=========================================+
 * llrpt_uniqueset -- Eliminate dupes from INDISEQ
 * usage: uniqueset(SET) -> VOID
 *========================================*/
PVALUE
llrpt_uniqueset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "uniqueset");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	unique_indiseq(seq);
	/* delay to last minute lest it is a temp owning seq,
	eg, uniqueset(ancestorset(i) */
	delete_pvalue(val1);
	return NULL;
}
Exemplo n.º 9
0
/*===========================================+
 * llrpt_deletefromset -- Remove person from INDISEQ
 * usage: deletefromset(SET, INDI, BOOL) -> VOID
 *==========================================*/
PVALUE
llrpt_deletefromset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	NODE indi;
	STRING key=0;
	BOOLEAN all, rc;
	INDISEQ seq;
	PNODE arg1 = builtin_args(node), arg2 = inext(arg1),
	    arg3 = inext(arg2);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	PVALUE val3=0;
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonsetx, "deletefromset", "1");
		goto dfs_exit;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	indi = eval_indi(arg2, stab, eflg, NULL);
	if (*eflg) {
		prog_var_error(node, stab, arg2, NULL, nonindx, "deletefromset", "2");
		goto dfs_exit;
	}
	if (!indi) goto dfs_exit;
	*eflg = TRUE;
	if (!(key = strsave(rmvat(nxref(indi))))) {
		prog_error(node, "major error in deletefromset.");
		goto dfs_exit;
	}
	*eflg = FALSE;
	val3 = eval_and_coerce(PBOOL, arg3, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg2, NULL, nonboox, "deletefromset", "3");
		goto dfs_exit;
	}
	all = pvalue_to_bool(val3);
	delete_pvalue(val3);
	do {
		rc = delete_indiseq(seq, key, NULL, 0);
	} while (rc && all);
dfs_exit:
	/* delay delete of val1 to last minute lest it is a temp owning seq,
	    eg, deletefromset(ancestorset(i),j) */
	if (val1) delete_pvalue(val1);
	if (key) strfree(&key);
	return NULL;
}
Exemplo n.º 10
0
/*======================================+
 * llrpt_indiset -- Declare an INDISEQ variable
 * usage: indiset(VARB) -> VOID
 *=====================================*/
PVALUE
llrpt_indiset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ newseq=0;
	PVALUE newval=0;
	PNODE arg1 = builtin_args(node);
	if (!iistype(arg1, IIDENT)) {
		*eflg = TRUE;
		prog_var_error(node, stab, arg1, NULL, nonvar1, "indiset");
		return NULL;
	}
	*eflg = FALSE;
	newseq = create_indiseq_pval();
	set_indiseq_value_funcs(newseq, &pvseq_fnctbl);
	newval = create_pvalue_from_seq(newseq);
	assign_iden(stab, iident_name(arg1), newval);
	/* gave val1 to stab, so don't clear it */
	return NULL;
}
Exemplo n.º 11
0
/*========================================+
 * llrpt_pagemode -- Switch output to page mode
 * usage: pagemode(INT, INT) -> VOID
 *======================================*/
PVALUE
llrpt_pagemode (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INT cols=0, rows=0;
	PNODE argvar = builtin_args(node);
	PVALUE val = eval_and_coerce(PINT, argvar, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonintx, "pagemode", "1");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	rows = pvalue_to_int(val);
	delete_pvalue_ptr(&val);
	val = eval_and_coerce(PINT, argvar=inext(argvar), stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonintx, "pagemode", "2");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	cols = pvalue_to_int(val);
	delete_pvalue_ptr(&val);
	*eflg = TRUE;
	if (!(cols >= 1 && cols <= MAXCOLS)) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, badargx, "pagemode", "1");
		return NULL;
	}
	if (!(rows >= 1 && rows <= MAXROWS)) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, badargx, "pagemode", "2");
		return NULL;
	}
	*eflg = FALSE;
	outputmode = PAGEMODE;
	__rows = rows;
	__cols = cols;
	if (pagebuffer) stdfree(pagebuffer);
	pagebuffer = (STRING) stdalloc(__rows*__cols);
	memset(pagebuffer, ' ', __rows*__cols);
	return NULL;
}
Exemplo n.º 12
0
/*===================================
 * llrpt_valuesort -- Sort INDISEQ by value
 * usage: valuesort(SET) -> VOID
 *=================================*/
PVALUE
llrpt_valuesort (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "valuesort");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	valuesort_indiseq(seq,eflg);
	if (*eflg) {
		prog_error(node, _("missing or incorrect value for sort"));
		return NULL;
	}
	/* delay to last minute lest it is a temp owning seq,
	eg, valuesort(ancestorset(i) */
	delete_pvalue(val1);
	return NULL;
}
Exemplo n.º 13
0
/*==================================+
 * llrpt_addtoset -- Add person to INDISEQ
 * usage: addtoset(SET, INDI, ANY) -> VOID
 *=================================*/
PVALUE
llrpt_addtoset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	NODE indi=0;
	STRING key=0;
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node), arg2 = inext(arg1),
	    arg3 = inext(arg2);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	PVALUE val2=0;
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonsetx, "addtoset", "1");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	indi = eval_indi(arg2, stab, eflg, NULL);
	if (*eflg) {
		prog_var_error(node, stab, arg2, NULL, nonindx, "addtoset","2");
		goto ats_exit;
	}
	if (!indi) goto ats_exit;
	*eflg = TRUE;
	if (!(key = strsave(rmvat(nxref(indi))))) {
		prog_error(node, "major error in addtoset.");
		goto ats_exit;
	}
	*eflg = FALSE;
	val2 = evaluate(arg3, stab, eflg);
	if (*eflg) {
		prog_error(node, "3rd arg to addtoset is in error.");
		goto ats_exit;
	}
	append_indiseq_pval(seq, key, NULL, val2, FALSE);
ats_exit:
	if (key) strfree(&key); /* append made its own copy */
	/* delay to last minute val1 cleanup lest it is a temp owning seq,
	    eg, addtoset(ancestorset(i),j) */
	if (val1) delete_pvalue(val1);
	return NULL;
}
Exemplo n.º 14
0
/*===============================================+
 * llrpt_pos -- Position page output to row and column
 * usage: pos(INT, INT) -> VOID
 *==============================================*/
PVALUE
llrpt_pos (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INT col=0, row=0;
	PNODE argvar = builtin_args(node);
	PVALUE val = eval_and_coerce(PINT, argvar, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonintx, "pos", "1");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	row = pvalue_to_int(val);
	if (row < 1 || row > __rows) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, badargx, "pos", "1");
		return NULL;
	}
	delete_pvalue_ptr(&val);
	val = eval_and_coerce(PINT, argvar=inext(argvar), stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonintx, "pos", "2");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	col = pvalue_to_int(val);
	if (col < 1 || col > __cols) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, badargx, "pos", "2");
		return NULL;
	}
	delete_pvalue_ptr(&val);
	if (outputmode != PAGEMODE) {
		*eflg = TRUE;
		prog_var_error(node, stab, NULL, val, "pos only valid in page mode");
		return NULL;
	}
	currow = row;
	curcol = col;
	return NULL;
}
Exemplo n.º 15
0
/*==================================+
 * llrpt_col -- Position output to column
 * usage: col(INT) -> VOID
 *=================================*/
PVALUE
llrpt_col (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INT newcol=0;
	PNODE argvar = builtin_args(node);
	PVALUE val = eval_and_coerce(PINT, argvar, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonint1, "col");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	newcol = pvalue_to_int(val);
	delete_pvalue_ptr(&val);
	if (newcol < 1) newcol = 1;
	if (newcol > MAXCOLS) newcol = MAXCOLS;
	if (newcol == curcol) return NULL;
	if (newcol < curcol)
		poutput("\n", eflg);
	while (curcol < newcol && !(*eflg))
		poutput(" ", eflg);
	return NULL;
}
Exemplo n.º 16
0
/*====================================+
 * llrpt_inset -- See if person is in INDISEQ
 * usage: inset(SET, INDI) -> BOOL
 *==========================================*/
PVALUE
llrpt_inset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	NODE indi;
	STRING key=0;
	INDISEQ seq;
	BOOLEAN rel;
	PNODE arg1 = builtin_args(node), arg2 = inext(arg1);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	PVALUE valr=0;
	if (*eflg ||!val1 || !(seq = pvalue_to_seq(val1))) {
		*eflg = TRUE;
		prog_var_error(node, stab, arg1, val1, nonsetx, "inset", "1");
		goto inset_exit;
	}
	indi = eval_indi(arg2, stab, eflg, NULL);
	if (*eflg) {
		prog_var_error(node, stab, arg2, NULL, nonindx, "inset", "2");
		goto inset_exit;
	}
	if (!indi) {
		rel = FALSE;
        } else { 
		if (!(key = strsave(rmvat(nxref(indi))))) {
			*eflg = TRUE;
			prog_error(node, "major error in inset.");
			goto inset_exit;
		}
		rel = in_indiseq(seq, key);
	}
	valr = create_pvalue_from_bool(rel);
inset_exit:
	/* delay delete of val1 to last minute lest it is a temp owning seq,
	    eg, inset(ancestorset(i),j) */
	if (val1) delete_pvalue(val1);
	if (key) strfree(&key);
	return valr;
}
Exemplo n.º 17
0
// This is where most of the strict/lazy distinction is.
static value_t *e_fncall(env_t *env, expr_t *fn, list_t *args)
{
  value_t *fnv;
  eli_closure_t c;

  // Call-by-need (lazy function calls): suspend (thunk-ify) each
  // argument in the given environment.
  c.env = env;
  c.list = list_empty();
  list_iterate(args, thunk_list_i, &c);
  list_reverse(c.list);

  // Due to C's 'break' being imperfect, use 'goto' for clarity.
 loop:

  // Evaluate the function to a closure/data constructor in the given
  // environment.
  fnv = e_expr(env, fn);

  switch (fnv->type) {

  case v_datacons:
    // Construct a new data constructor value; we need to do this in
    // case the value we got from evaluating the "function" is shared.
    {
      value_t *dcv = alloc_value(v_datacons);

      datacons_tag(dcv) = datacons_tag(fnv);
      datacons_params(dcv) = list_append_new(datacons_params(fnv), c.list);

      fnv = dcv;
    }
    break;

  case v_closure:
    {
      int paramsArgs;

      // Bind the closure's parameters to the given arguments in a new
      // environment. At this point the original environment has
      // served its purpose.
      env = closure_env(fnv);

      env_new_scope(&env);
      paramsArgs = list_zip_with(closure_params(fnv),
                		 c.list,
                		 e_bind_params_i, env);

      // See how the number of parameters and arguments relate.
      switch (paramsArgs) {
      case -1:
        // Didn't get enough arguments, so wait for some more by
        // building a new closure.
        {
          value_t *fn_unsaturated = alloc_value(v_closure);

          closure_params(fn_unsaturated) = list_drop_new(list_length(c.list), closure_params(fnv));
          closure_body(fn_unsaturated) = closure_body(fnv);
          closure_env(fn_unsaturated) = env;

          fnv = fn_unsaturated;
        }
        break;

      case 0:
        // Got exactly the right number of arguments. Evaluate the
        // body in the extended environment.
        fnv = e_expr(env, closure_body(fnv));
        break;

      case 1:
        // Got too many arguments for this closure. Assuming
        // type-correctness, that implies the body of this closure
        // reduces to a function, so let's try again. Note the
        // environment has already been updated.

        fn = closure_body(fnv);
        c.list = list_drop_new(list_length(closure_params(fnv)), c.list);

        goto loop;
      }
      break;

    case v_builtin_fn:
      {
        int nArgs;
        int nParams;

        // See how the number of parameters and arguments relate.
        nArgs = list_length(c.list);
        nParams = builtin_num_params(fnv);

        if (nArgs < nParams) {
          // Didn't get enough arguments, so wait for some more by
          // building a new closure-like thing.
          value_t *fn_unsaturated = alloc_value(v_builtin_fn);

          builtin_num_params(fn_unsaturated) = nParams - nArgs;
          builtin_args(fn_unsaturated) = builtin_args(fnv);
          list_append(&builtin_args(fn_unsaturated), &c.list);
          builtin_fn(fn_unsaturated) = builtin_fn(fnv);

          return fn_unsaturated;
        } else if (nArgs > nParams) {
          // Got too many arguments. Assuming type-correctness, that
          // implies the built-in function returns a function closure,
          // so let's try again.

          // FIXME
          error("builtin function application is over-saturated.\n");
          return NULL;
// 	  value_t *result = builtin_fn(fnv)(list_take_new(builtin_num_params(fnv), c.list));

// 	  fncall_fn(expr) = closure_body(fnv);
// 	  c.list = list_drop_new(nParams, c.list);
// 	  env = fn_env;

// 	  break; /\* Loop *\/
        } else {
          // Got exactly the right number of arguments.
          return builtin_fn(fnv)(c.list);
        }
      }
      break;

    default:
      fprintf(stdout, "e_fncall: expression:\n");
      pp_expr(stdout, fn, 2);
      fprintf(stdout, "\non line %d evaluated to non-function/data constructor value:\n", fn->line_num);
      print_value(stdout, fnv);
      error("\n");
      break;
    }
  }

  return fnv;
}