Beispiel #1
0
int picolCondition(picolInterp *i, char* str)
{
    if(str) {
        char buf[MAXSTR], buf2[MAXSTR];
        int rc;
        rc = picolSubst(i,str);
        if(rc != PICOL_OK) return rc;
        //mysnprintf(buf, MAXSTR, "Condi: (%s) ->(%s)\n",str,i->result);
        //dbg_send_str3(buf, 1);
        mystrncpy(buf2,i->result, MAXSTR);
        /* ------- try whether the format suits [expr]... */
        mystrncpy(buf,"llength ", MAXSTR); LAPPEND(buf,i->result);
        //dbg_send_str3(buf, 1);
        rc = picolEval(i,buf);
        if(rc != PICOL_OK) return rc;
#if 0
        if(EQ(i->result,"3")) {
            FOREACH(buf,cp,buf2) argv[a++] = mystrdup(buf);
            if(picolGetCmd(i,argv[1])) { /* defined operator in center */
                mystrncpy(buf,argv[1], MAXSTR);       /* translate to Polish :) */
                LAPPEND(buf,argv[0]);      /* e.g. {1 > 2} -> {> 1 2} */
                LAPPEND(buf,argv[2]);
                rc = picolEval(i, buf);
                return rc;
            }
        } /* .. otherwise, check for inequality to zero */
#endif
        if(*str == '!') {mystrncpy(buf, "== 0 ", MAXSTR); str++;} /* allow !$x */
        else             mystrncpy(buf, "!= 0 ", MAXSTR);
        mystrncat(buf, str, MAXSTR);
        return picolEval(i, buf); // todo: compare without eval
    }
    else
        return picolErr(i, "NULL condition");
}
Beispiel #2
0
int main(int argc, char **argv) {
    struct picolInterp interp;
    picolInitInterp(&interp);
    picolRegisterCoreCommands(&interp);
    if (argc == 1) {
        while(1) {
            char clibuf[1024];
            int retcode;
            printf("picol> "); fflush(stdout);
            if (fgets(clibuf,1024,stdin) == NULL) return 0;
            retcode = picolEval(&interp,clibuf);
            if (interp.result[0] != '\0')
                printf("[%d] %s\n", retcode, interp.result);
        }
    } else if (argc == 2) {
        char buf[1024*16];
        FILE *fp = fopen(argv[1],"r");
        if (!fp) {
            perror("open"); exit(1);
        }
        buf[fread(buf,1,1024*16,fp)] = '\0';
        fclose(fp);
        if (picolEval(&interp,buf) != PICOL_OK) printf("%s\n", interp.result);
    }
    return 0;
}
int picol_main(int argc, char **argv) {
	static struct picolInterp interp;
	picolInitInterp(&interp);
	picolRegisterCoreCommands(&interp);
	if (1) {
		while (1) {
			static char clibuf[256];
			int retcode;
			iprintf("picol> ");
			fflush(stdout);
			interpreter_readline(clibuf, sizeof(clibuf));
			retcode = picolEval(&interp, clibuf);
			if (interp.result[0] != '\0')
				iprintf("[%d] %s\n", retcode, interp.result);
		}
	}
#if 0
	else if (argc == 2) {
		char buf[1024 * 16];
		FILE *fp = fopen(argv[1], "r");
		if (!fp) {
			perror("open");
			return 1;
		}
		buf[fread(buf, 1, 1024 * 16, fp)] = '\0';
		fclose(fp);
		if (picolEval(&interp, buf) != PICOL_OK)
			iprintf("%s\n", interp.result);
	}
#endif
	return 0;
}
Beispiel #4
0
int picolCommandIf(struct picolInterp *i, int argc, char **argv, void *pd) {
    int retcode;
    if (argc != 3 && argc != 5) return picolArityErr(i,argv[0]);
    if ((retcode = picolEval(i,argv[1])) != PICOL_OK) return retcode;
    if (atoi(i->result)) return picolEval(i,argv[2]);
    else if (argc == 5) return picolEval(i,argv[4]);
    return PICOL_OK;
}
Beispiel #5
0
int picolCommandWhile(struct picolInterp *i, int argc, char **argv, void *pd) {
    if (argc != 3) return picolArityErr(i,argv[0]);
    while(1) {
        int retcode = picolEval(i,argv[1]);
        if (retcode != PICOL_OK) return retcode;
        if (atoi(i->result)) {
            if ((retcode = picolEval(i,argv[2])) == PICOL_CONTINUE) continue;
            else if (retcode == PICOL_OK) continue;
            else if (retcode == PICOL_BREAK) return PICOL_OK;
            else return retcode;
        } else {
            return PICOL_OK;
        }
    }
}
Beispiel #6
0
int picolCommandCallProc(struct picolInterp *i, int argc, char **argv, void *pd) {
    char **x=pd, *alist=x[0], *body=x[1], *p=strdup(alist), *tofree;
    struct picolCallFrame *cf = malloc(sizeof(*cf));
    int arity = 0, done = 0, errcode = PICOL_OK;
    char errbuf[1024];
    cf->vars = NULL;
    cf->parent = i->callframe;
    i->callframe = cf;
    tofree = p;
    while(1) {
        char *start = p;
        while(*p != ' ' && *p != '\0') p++;
        if (*p != '\0' && p == start) {
            p++; continue;
        }
        if (p == start) break;
        if (*p == '\0') done=1; else *p = '\0';
        if (++arity > argc-1) goto arityerr;
        picolSetVar(i,start,argv[arity]);
        p++;
        if (done) break;
    }
    free(tofree);
    if (arity != argc-1) goto arityerr;
    errcode = picolEval(i,body);
    if (errcode == PICOL_RETURN) errcode = PICOL_OK;
    picolDropCallFrame(i); /* remove the called proc callframe */
    return errcode;
arityerr:
    snprintf(errbuf,1024,"Proc '%s' called with wrong arg num",argv[0]);
    picolSetResult(i,errbuf);
    picolDropCallFrame(i); /* remove the called proc callframe */
    return PICOL_ERR;
}
Beispiel #7
0
int picolCallProc(picolInterp *i, int argc, char **argv)
{
    if(i->level>MAXRECURSION)
        return picolErr(i,"too many nested evaluations (infinite loop?)");
    picolCmd *c = picolGetCmd(i,argv[0]);
    if(!c)
        return PICOL_ERR;
    void *pd = c->privdata;
    if(!pd)
        return PICOL_ERR;
    char **x=pd;
    char *alist=x[0], *body=x[1];
    char buf[MAXSTR];
    picolCallFrame *cf = mycalloc(1,sizeof(*cf));
    int a = 0, done = 0, errcode = PICOL_ERR;
#ifndef __arm__
    if(!cf) {printf("could not allocate callframe\n"); exit(1);}
#else
    extern void print1(char *str);
    if(!cf) {dbg_send_str3("could not allocate callframe", 1); return PICOL_ERR;}
#endif
    cf->parent   = i->callframe;
    i->callframe = cf;
    i->level++;
    char *p = mystrdup(alist);
    while(1) {
        char *start = p;
        while(*p != ' ' && *p != '\0') p++;
        if (*p != '\0' && p == start) { p++; continue; }
        if (p == start) break;
        if (*p == '\0') done=1; else *p = '\0';
        if(EQ(start,"args") && done) {
            dbg_send_hex2("eq", p - alist);
            picolSetVar(i,start,picolList1(buf,argc-a-1,argv+a+1));
            a = argc-1;
            break;
        }
        if (++a > argc-1)
            break;
        picolSetVar(i,start,argv[a]);
        p++;
        if (done) break;
    }
    if (a == argc-1)
        errcode = picolEval(i,body);
    else
        errcode = picolErr1(i,"wrong # args for '%s'",argv[0]);
    if (errcode == PICOL_RETURN)
        errcode = PICOL_OK;
    i->callframe = cf->parent;
    myfree(cf);
    i->level--;
    return errcode;
}
Beispiel #8
0
uint16_t pcl_load(picolInterp *i, uint32_t addr)
{
    uint8_t *ptr = (uint8_t*)addr;
    dbg_send_hex2("pcl_load.addr", (uint32_t)ptr);
    int32_t fsz = (int32_t)flash_fsz1();
    uint32_t len = 0;
    uint16_t rc = PICOL_OK;
    char buf[MAXSTR];
    if(!fsz)
        return rc;
    while(1)
    {
        dbg_send_int2("pcl_load.fsz", fsz);
        while((ptr[0] == 0x0A) && (fsz > 0))
        {
            ptr++;
            fsz--;
        }
        len = pcl_get_chunksz(ptr, fsz);
        dbg_send_int2("pcl_load.len", len);
        if(len == 0)
            break;
        if(len >= sizeof(buf))
        {
            dbg_send_int2("chunk too big", len);
            dbg_send_int2("fsz", fsz);
            dbg_send_int2("ptr", (int32_t)(ptr - addr));
            break;
        }
        mymemcpy(buf, ptr, len);
        buf[len] = 0;
        dbg_send_str3(buf, 1);
        //pcl_exec(buf);
        dbg_send_str3(buf, 1);
        rc = picolEval(i, buf);
        dbg_send_int2("pcl_load_eval_result", rc);
        if(rc != PICOL_OK)
        {
            dbg_send_str3("pcl_load error", 1);
            dbg_send_str3(i->result, 1);
            break;
        }
        ptr += len + 1;
        fsz -= len + 1;
        if(fsz <= 0)
            break;
    }
    dbg_send_int2("pcl_load.fsz", fsz);
    return rc;
}
Beispiel #9
0
int picolEval2(picolInterp *i, const char *t, int mode) { /*----------- EVAL! */
    /* mode==0: subst only, mode==1: full eval */
    picolParser p;
    char        buf[MAXSTR], tmp[MAXSTR], sep = 0;
    if(mode == 0)
        sep = ' ';
    uint32_t    len;
    int         rc = PICOL_OK;
    picolList args; args.size = 0;
    picolSetResult(i, "");
    picolInitParser(&p, t);
    while(1) {
        picolGetToken(i, &p);
        //___print_token(&p);
        if (p.type == PT_EOF)
            break;
        len = p.end - p.start + 1;
        mystrncpy(tmp, p.start, len);
        //___print_list(&args);
        if (p.type == PT_SEP) {
            continue;
        }
        else if (p.type == PT_VAR) {
            picolVar *v = picolGetVar(i,tmp);
            if (v && !v->val) v = picolGetGlobalVar(i,tmp);
            if(!v)
                return picolErr(i,"no such variable");
            picolListAppend(&args, v->val, buf, sep);
            //___print_list(&args);
            continue;
        } else if (p.type == PT_CMD) {
            rc = picolEval(i,tmp);
            if (rc != PICOL_OK)
                break;
            picolListAppend(&args, i->result, buf, sep);
            continue;
        }
        /* We have a complete command + args. Call it! */
        else if (p.type == PT_EOL) {
            picolCmd *c;
            //args.size -= 1;
            if(mode==0) { /* do a quasi-subst only */
                rc = picolSetResult(i, buf);
                goto err; /* not an error, if rc == PICOL_OK */
            }
            if (args.size) {
                if ((c = picolGetCmd(i,args.table[0])) == NULL) {
                    rc = picolErr(i,"invalid command name");
                    goto err;
                }
                rc = c->func(i,args.size,args.table);
                if (rc != PICOL_OK) goto err;
                args.size = 0;
                continue;
            }
            args.size = 0;
            continue;
        }
        else
            picolListAppend(&args, tmp, buf, sep);
    }
err:
    return rc;
}
Beispiel #10
0
/* EVAL! */
int picolEval(struct picolInterp *i, char *t) {
	struct picolParser p;
	int argc = 0, j;
	char **argv = NULL;
	int retcode = PICOL_OK;
	picolSetResult(i, "");
	picolInitParser(&p, t);
	while (1) {
		char *t;
		int tlen;
		int prevtype = p.type;
		picolGetToken(&p);
		if (p.type == PT_EOF)
			break;
		tlen = p.end - p.start + 1;
		if (tlen < 0)
			tlen = 0;
		t = my_malloc(tlen + 1);
		memcpy(t, p.start, tlen);
		t[tlen] = '\0';
		if (p.type == PT_VAR) {
			struct picolVar *v = picolGetVar(i, t);
			if (!v) {
				iprintf("No such variable '%s'", t);
				free(t);
				// picolSetResult(i, errbuf);
				retcode = PICOL_ERR;
				goto err;
			}
			free(t);
			t = strdup(v->val);
		} else if (p.type == PT_CMD) {
			retcode = picolEval(i, t);
			free(t);
			if (retcode != PICOL_OK)
				goto err;
			t = strdup(i->result);
		} else if (p.type == PT_ESC) {
			/* XXX: escape handling missing! */
		} else if (p.type == PT_SEP) {
			prevtype = p.type;
			free(t);
			continue;
		}
		/* We have a complete command + args. Call it! */
		if (p.type == PT_EOL) {
			struct picolCmd *c;
			free(t);
			prevtype = p.type;
			if (argc) {
				if ((c = picolGetCommand(i, argv[0])) == NULL) {
					iprintf("No such command '%s'", argv[0]);
					// picolSetResult(i, errbuf);
					retcode = PICOL_ERR;
					goto err;
				}
				retcode = c->func(i, argc, argv, c->privdata);
				if (retcode != PICOL_OK)
					goto err;
			}
			/* Prepare for the next command */
			for (j = 0; j < argc; j++)
				free(argv[j]);
			free(argv);
			argv = NULL;
			argc = 0;
			continue;
		}
		/* We have a new token, append to the previous or as new arg? */
		if (prevtype == PT_SEP || prevtype == PT_EOL) {
			argv = realloc(argv, sizeof(char*) * (argc + 1));
			argv[argc] = t;
			argc++;
		} else { /* Interpolation */
			int oldlen = strlen(argv[argc - 1]), tlen = strlen(t);
			argv[argc - 1] = realloc(argv[argc - 1], oldlen + tlen + 1);
			memcpy(argv[argc - 1] + oldlen, t, tlen);
			argv[argc - 1][oldlen + tlen] = '\0';
			free(t);
		}
		prevtype = p.type;
	}
	err: for (j = 0; j < argc; j++)
		free(argv[j]);
	free(argv);
	return retcode;
}