Esempio n. 1
0
/// Do the first for part.
void tag_for(parser_status *st, list *l){
	function_add_code(st, 
"  {\n"
"    onion_dict *loopdict=onion_dict_get_dict(context, \"%s\");\n", tag_value_arg (l,3));
	function_add_code(st, 
"    onion_dict *tmpcontext=onion_dict_hard_dup(context);\n"
"    if (loopdict){\n"
"      dict_res dr={ .dict = tmpcontext, .res=res };\n"
"      onion_dict_preorder(loopdict, ");
	function_data *d=function_new(st, NULL);
	d->signature="dict_res *dr, const char *key, const void *value, int flags";

	function_add_code(st, 
"  onion_dict_add(dr->dict, \"%s\", value, OD_DUP_VALUE|OD_REPLACE|(flags&OD_TYPE_MASK));\n", tag_value_arg(l,1));
	
	function_new(st, NULL);
}
Esempio n. 2
0
/// Include an external html. This is only the call, the programmer must compile such html too.
void tag_include(parser_status* st, list* l){
	function_data *d=function_new(st, "%s", tag_value_arg(l, 1));
	function_pop(st);
	onion_block_free(d->code); // This means no impl
	d->code=NULL; 
	
	function_add_code(st, "  %s(context, res);\n", d->id);
}
Esempio n. 3
0
void tag_extends(parser_status *st, list *l){
	function_data *d=function_new(st, "%s", tag_value_arg(l, 1));
	function_pop(st);
	onion_block_free(d->code);
	d->code=NULL;
	
	function_add_code(st, "  %s(context, res);", d->id);
	d=(function_data*)st->function_stack->tail->data;
	d->flags|=F_NO_MORE_WRITE;
}
Esempio n. 4
0
static void
process_args(char *name)
{
	struct function *func;
	struct symbol *arg;

	/*(*/
	consume_token();

	func = function_table_lookup(name);

	/* Delete an old function and make a new one */
	if (func != NULL) 
		function_table_delete_function(name);	

	func = function_new(name);
	
	while (!match(TOKEN_RPARENTH)) {
		if (match(TOKEN_EOL)) {
			error_msg("error: new line in function definition");
			return;	
		}
		
		if (!match(TOKEN_ID)) {
			error_msg("error: unexpected symbol in definition");
			sync_stream();
			ufree(func);
			return;
		}
	
		arg = symbol_new(lex_prev.id, VALUE_TYPE_UNKNOWN);
		
		function_add_arg(func, arg);
		
		if (current_token != TOKEN_RPARENTH && !match(TOKEN_COMMA)) {
			error_msg("error: comma expected");
			sync_stream();
			return;
		}			
	}

	switch(current_token) {
	case TOKEN_LBRACE:
		function_table_insert(func);
		process_function_body(name);
		break;
	default:
		error_msg("error: `{' expected");
		sync_stream();
		break;
	}	
}
Esempio n. 5
0
static gpointer
function_dup(gconstpointer data)
{
	const function_t *org = data;
	function_t		 *stfuncrec;
	GSList *p;

	stfuncrec = function_new(org->funcdef);

	for (p = org->params; p; p = p->next) {
		const stnode_t *param = p->data;
		stfuncrec->params = g_slist_append(stfuncrec->params, stnode_dup(param));
	}
	return (gpointer) stfuncrec;
}
Esempio n. 6
0
void tag_block(parser_status *st, list *l){
	const char *block_name=tag_value_arg(l, 1);
	function_add_code(st, 
"  {\n"
"    void (*f)(onion_dict *context, onion_response *res);\n"
"    f=(void*)onion_dict_get(context, \"__block_%s__\");\n"
"    if (f)\n"
"      f(context, res);\n"
"  }\n", block_name);

	char tmp[256];
	strncpy(tmp, st->infilename, sizeof(tmp));
	function_data *d=function_new(st, "%s__block_%s", basename(tmp),  block_name);
	function_add_code_f(st->blocks_init, 
"  if (!onion_dict_get(context, \"__block_%s__\"))\n"
"    onion_dict_add(context, \"__block_%s__\", %s, 0);\n", block_name, block_name, d->id);
}
Esempio n. 7
0
/// Starts an if
void tag_if(parser_status *st, list *l){
	int lc=list_count(l);
	if (lc==2){
		function_add_code(st, 
"  {\n"
"    const char *tmp;\n"
		);
		variable_solve(st, tag_value_arg(l, 1), "tmp", tag_type_arg(l,1));
		function_add_code(st, 
"    if (tmp && strcmp(tmp, \"false\")!=0)\n", tag_value_arg(l,1));
	}
	else if (lc==4){
		const char *op=tag_value_arg(l, 2);
		const char *opcmp=NULL;
		if (strcmp(op,"==")==0)
			opcmp="==0";
		else if (strcmp(op,"<=")==0)
			opcmp="<=0";
		else if (strcmp(op,"<")==0)
			opcmp="<0";
		else if (strcmp(op,">=")==0)
			opcmp=">=0";
		else if (strcmp(op,">")==0)
			opcmp=">0";
		else if (strcmp(op,"!=")==0)
			opcmp="!=0";
		if (opcmp){
			function_add_code(st,
"  {\n"
"    const char *op1, *op2;\n");
			variable_solve(st, tag_value_arg(l, 1), "op1", tag_type_arg(l,1));
			variable_solve(st, tag_value_arg(l, 3), "op2", tag_type_arg(l,3));
			function_add_code(st,
"    if (op1==op2 || (op1 && op2 && strcmp(op1, op2)%s))\n",opcmp);
		}
		else{
			ONION_ERROR("%s:%d Unkonwn operator for if: %s", st->infilename, st->line, op);
			st->status=1;
		}
	}
	else{
		ONION_ERROR("%s:%d If only allows 1 or 3 arguments. TODO. Has %d.", st->infilename, st->line, lc-1);
		st->status=1;
	}
	function_new(st, NULL);
}
Esempio n. 8
0
int test_function_new_and_destroy(void)
{
    f = function_new(DEFAULT, 0, 2);
    mu_check(f->type == DEFAULT);
    mu_check(f->function == 0);
    mu_check(f->arity == 2);
    function_destroy(f);

    /* default function */
    f = function_new_func(0, 2);
    mu_check(f->type == DEFAULT);
    mu_check(f->function == 0);
    mu_check(f->arity == 2);
    function_destroy(f);

    /* classification function */
    f = function_new_cfunc(0, 2);
    mu_check(f->type == CLASSIFICATION);
    mu_check(f->function == 0);
    mu_check(f->arity == 2);
    function_destroy(f);

    return 0;
}
Esempio n. 9
0
/// Else part
void tag_else(parser_status *st, list *l){
	function_data *d=function_pop(st);
	function_add_code(st, "      %s(context, res);\n    else\n", d->id);
	
	function_new(st, NULL);
}
Esempio n. 10
0
File: parser.c Progetto: bieber/col
// Parses a function definition
struct function *parse_function(struct lexer_state *lexer)
{
    int error = 0;
    int i = 0;
    struct function *function = NULL;

    // First getting the identifier
    lex(lexer);

    if(lexer->error == UNRECOGNIZED_TOKEN)
    {
        print_error(lexer, LEX_ERROR);
        return NULL;
    }
    
    if(lexer->error == END_OF_INPUT)
    {
        print_error(lexer, UNEXPECTED_END);
        return NULL;
    }

    if(lexer->type != IDENT)
    {
        print_error(lexer, EXPECTED_IDENT);
        return NULL;
    }

    // Storing the identifier
    function = function_new();
    function->name = strdup(lexer->value.sval);

    // Figuring out what type of function this is
    function->type = USER; // Until proven otherwise

    // Checking against primitive and form lists
    for(i = 0; *(PRIMITIVE_FUNCTION_NAMES[i]); i++)
    {
        if(!strcmp(PRIMITIVE_FUNCTION_NAMES[i], function->name))
        {
            function->type = PRIMITIVE;
            function->index = i;
        }
    }
    
    for(i = 0; *(FUNCTIONAL_FORM_NAMES[i]); i++)
    {
        if(!strcmp(FUNCTIONAL_FORM_NAMES[i], function->name))
        {
            function->type = FORM;
            function->index = i;
        }
    }

    // Now checking for possible arguments
    if(function->type == PRIMITIVE)
    {
        lex(lexer);
        
        if(lexer->error == UNRECOGNIZED_TOKEN)
        {
            print_error(lexer, LEX_ERROR);
            function_delete(function);
            return NULL;
        }

        // Now checking for opening paren
        if(lexer->error == OK && lexer->type == OPEN_SPEC)
        {
            function->args = parse_constant_args(lexer, CLOSE_SPEC);
            if(!function->args)
            {
                function_delete(function);
                return NULL;
            }
        }
        else
        {
            lexer_rewind(lexer);
        }
    }
    else if(function->type == FORM)
    {
        // A functional form requires arguments
        if(!require_token(lexer, OPEN_FORM))
        {
            print_error(lexer, EXPECTED_ARGS);
            function_delete(function);
            return NULL;
        }

        function->args = parse_function_args(lexer);
        if(!function->args)
        {
            function_delete(function);
            return NULL;
        }
    }
    
    return function;
}
Esempio n. 11
0
/**
 * @short Compiles the infilename to outfilename.
 */
int work(const char *infilename, const char *outfilename, onion_assets_file *assets){
	tag_init();
	parser_status status;
	memset(&status, 0, sizeof(status));
	status.mode=TEXT;
	status.functions=list_new((void*)function_free);
	status.function_stack=list_new(NULL);
	status.status=0;
	status.line=1;
	status.rawblock=onion_block_new();
	status.infilename=infilename;
	char tmp2[256];
	strncpy(tmp2, infilename, sizeof(tmp2)-1);
	const char *tname=basename(tmp2);
  ONION_DEBUG("Create init function on top, tname %s",tname);
	status.blocks_init=function_new(&status, "%s_blocks_init", tname);
	status.blocks_init->signature="onion_dict *context";
	
	if (strcmp(infilename, "-")==0)
		status.in=stdin;
	else
		status.in=fopen(infilename,"rt");
	
	if (!status.in){
		ONION_ERROR("Could not open in file %s", infilename);
		goto work_end;
	}

	ONION_DEBUG("Create main function on top, tname %s",tname);
	function_new(&status, tname);
	
	function_add_code(&status, 
"  int has_context=(context!=NULL);\n"
"  if (!has_context)\n"
"    context=onion_dict_new();\n"
"  \n"
"  %s(context);\n",  status.blocks_init->id);
	
	parse_template(&status);
	
	((function_data*)status.function_stack->tail->data)->flags=0;
	
	function_add_code(&status,
"  if (!has_context)\n"
"    onion_dict_free(context);\n"
	);
	
	if (status.status){
		ONION_ERROR("Parsing error");
		goto work_end;
	}

	if (strcmp(outfilename, "-")==0)
		status.out=stdout;
	else
		status.out=fopen(outfilename,"wt");
	if (!status.out){
		ONION_ERROR("Could not open out file %s", infilename);
		goto work_end;
	}
	
	fprintf(status.out,
"/** Autogenerated by otemplate v. 0.2.0 */\n"
"\n"
"#include <libintl.h>\n"
"#include <string.h>\n\n"
"#include <onion/onion.h>\n"
"#include <onion/dict.h>\n"
"\n"
"typedef struct dict_res_t{\n"
"	onion_dict *dict;\n"
"	onion_response *res;\n"
"}dict_res;\n"
"\n"
"\n");

	functions_write_declarations_assets(&status, assets);
	
	functions_write_declarations(&status);

	functions_write_main_code(&status);

	if (use_orig_line_numbers)
		fprintf(status.out, "#line 1 \"%s\"\n", infilename);

	functions_write_code(&status);

work_end:
	if (status.in)
		fclose(status.in);
	if (status.out)
		fclose(status.out);
	list_free(status.functions);
	list_free(status.function_stack);
	//list_free(status.blocks);
	onion_block_free(status.rawblock);
	
	tag_free();
	return status.status;
}
Esempio n. 12
0
static int 
place_function (xmlDocPtr doc, xmlNodePtr node, sectlist *s)
{
    xmlNodePtr n1, n2;
    function *fun, **funs = NULL;
    char *sname, *fname, *atype, *retval;
    int matrix_ok = 0;
    int gotargs = 0;
    int nc, n = -1;
    int i, err = 0;

    sname = (char *) xmlGetProp(node, (UTF) "section");
    fname = (char *) xmlGetProp(node, (UTF) "name");
    retval = (char *) xmlGetProp(node, (UTF) "output");

    if (!function_in_gretl(fname)) {
	fprintf(stderr, "*** '%s': obsolete function, skipping\n", fname);
	goto bailout;
    }
    
    if (sname == NULL || fname == NULL || retval == NULL) {
	fprintf(stderr, "Error parsing function\n");
	return 1;
    }

    if (matrix_return(retval)) {
	matrix_ok = 1;
    } else {
	n1 = node->xmlChildrenNode;
	while (n1 != NULL && !err && !gotargs) {
	    if (!xmlStrcmp(n1->name, (UTF) "fnargs")) {
		gotargs = 1;
		n2 = n1->xmlChildrenNode;
		while (n2 != NULL && !err && !matrix_ok) {
		    if (!xmlStrcmp(n2->name, (UTF) "fnarg")) {
			atype = (char *) xmlGetProp(n2, (UTF) "type");
			if (ok_matrix_arg(atype)) {
			    matrix_ok = 1;
			}
			free(atype);
		    }
		    n2 = n2->next;
		}
	    }
	    n1 = n1->next;
	} 
    }  

    if (!matrix_ok) {
	goto bailout;
    }

    for (i=0; i<s->nsects; i++) {
	if (!strcmp(sname, s->sections[i]->name)) {
	    n = i;
	    break;
	}
    }

    if (n < 0) {
	/* assume this function is not wanted, in context */
	goto bailout;
    }

    fun = function_new(fname, matrix_ok);
    if (fun == NULL) {
	fprintf(stderr, "Out of memory\n");
	return 1;
    }

    nc = s->sections[n]->nfuns + 1;
    funs = realloc(s->sections[n]->funs, nc * sizeof *funs);
    if (funs == NULL) {
	fprintf(stderr, "Out of memory\n");
	return 1;
    }
	
    s->sections[n]->funs = funs;
    s->sections[n]->funs[nc-1] = fun;
    s->sections[n]->nfuns = nc;

#if VERBOSE
    fprintf(stderr, "Added function '%s' to section '%s'\n", fname, sname);
#endif

 bailout:

    free(fname);
    free(sname);

    return err;
}