implicit multiply, negatives, solve

master
Clyne Sullivan 7 years ago
parent 40e157ffa2
commit 28447df15a

@ -13,6 +13,7 @@ int ifunc_do(interpreter *it);
int ifunc_while(interpreter *it); int ifunc_while(interpreter *it);
int ifunc_ret(interpreter *it); int ifunc_ret(interpreter *it);
int ifunc_else(interpreter *it); int ifunc_else(interpreter *it);
int ifunc_solve(interpreter *it);
const func_t indent_up[IUP_COUNT] = { const func_t indent_up[IUP_COUNT] = {
ifunc_if, ifunc_do, ifunc_label ifunc_if, ifunc_do, ifunc_label
@ -32,6 +33,24 @@ void iload_core(interpreter *interp)
inew_cfunc(interp, "while", ifunc_while); inew_cfunc(interp, "while", ifunc_while);
inew_cfunc(interp, "ret", ifunc_ret); inew_cfunc(interp, "ret", ifunc_ret);
inew_cfunc(interp, "else", ifunc_else); inew_cfunc(interp, "else", ifunc_else);
inew_cfunc(interp, "solve", ifunc_solve);
}
int ifunc_solve(interpreter *it)
{
const char *expr = igetarg_string(it, 0);
int len = strlen(expr);
char *buf = (char *)malloc(len + 2);
strcpy(buf, expr);
buf[len] = ')';
buf[len + 1] = '\0';
variable *r = idoexpr(it, buf);
free(buf);
if (r == 0)
r = make_varn(0, 0.0f);
iret(it, r);
free(r);
return 0;
} }
int ifunc_set(interpreter *it) int ifunc_set(interpreter *it)

@ -14,9 +14,6 @@
#define MAX_STACK 32 #define MAX_STACK 32
#define MAX_LINES 1000 #define MAX_LINES 1000
extern int atoi(const char *);
extern float strtof(const char *, char **);
void iinit(interpreter *interp) void iinit(interpreter *interp)
{ {
interp->vars = (variable *)calloc(MAX_VARS, sizeof(variable)); interp->vars = (variable *)calloc(MAX_VARS, sizeof(variable));
@ -47,6 +44,9 @@ void iend(interpreter *it)
for (unsigned int j = 0; (int32_t)it->lines[i][j] > 0; j++) { for (unsigned int j = 0; (int32_t)it->lines[i][j] > 0; j++) {
switch (it->lines[i][j]->valtype) { switch (it->lines[i][j]->valtype) {
case STRING: case STRING:
if (!it->lines[i][j]->used)
free(it->lines[i][j]);
break;
case EXPR: case EXPR:
free((void *)it->lines[i][j]->value.p); free((void *)it->lines[i][j]->value.p);
free(it->lines[i][j]); free(it->lines[i][j]);
@ -156,44 +156,22 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next)
variable *v = make_vare(0, expr); variable *v = make_vare(0, expr);
free(expr); free(expr);
return v; return v;
} else if (isalpha(line[0])) { // variable/func } else {
uint32_t end = 1; variable *v = make_varn(0, 0.0f);
for (; isalnum(line[end]); end++); int inc = try_number(v, line);
if (!eot(line[end])) if (inc != 0) {
return 0; *next = inc;
char *name = (char *)malloc(end + 1); return v;
strncpy(name, line, end); }
name[end] = '\0'; free(v);
*next = end; char *name = 0;
variable *v = interpreter_get_variable(interp, name); inc = try_variable(&name, line);
free(name); if (inc != 0) {
return v; *next = (inc > 0) ? inc : -inc;
} else if (isdigit(line[0])) { // number variable *v = interpreter_get_variable(interp, name);
uint32_t end = 1; free(name);
uint8_t dec = 0; return v;
for (; !eot(line[end]); end++) {
if (!isdigit(line[end])) {
if (line[end] == '.') {
if (!dec)
dec = 1;
else
return 0;
} else {
return 0;
}
}
} }
char *copy = (char *)malloc(end + 1);
strncpy(copy, line, end);
copy[end] = '\0';
variable *v;
if (dec)
v = make_varn(0, strtof(copy, 0));
else
v = make_varn(0, (float)atoi(copy));
free(copy);
*next = end;
return v;
} }
return 0; return 0;
} }
@ -364,7 +342,6 @@ variable *idoexpr(interpreter *interp, const char *line)
void *ops[16]; void *ops[16];
uint32_t ooffset = 0; uint32_t ooffset = 0;
uint32_t offset = 0; uint32_t offset = 0;
uint32_t next = 0;
// step 1 - break apart line // step 1 - break apart line
for (uint8_t i = 0; i < 16; i++) for (uint8_t i = 0; i < 16; i++)
@ -392,17 +369,33 @@ variable *idoexpr(interpreter *interp, const char *line)
ops[ooffset] = idoexpr(interp, line + offset + 1); ops[ooffset] = idoexpr(interp, line + offset + 1);
offset = i + 1; offset = i + 1;
} else { } else {
uint32_t len = offset; variable *v = make_varn(0, 0.0f);
for (; isalnum(line[len]) || line[len] == '.'; len++); int inc = try_number(v, line + offset);
len -= offset; if (inc != 0) {
char *copy = (char *)malloc(len + 1); ops[ooffset] = v;
strncpy(copy, line + offset, len); offset += inc;
copy[len] = '\0'; } else {
variable *v = make_var(interp, copy, &next); free(v);
free(copy); char *name;
ops[ooffset] = v; inc = try_variable(&name, line + offset);
offset += next; if (inc != 0) {
v = interpreter_get_variable(interp, name);
ops[ooffset] = v;
free(name);
if (inc < 0) {
inc = -inc;
ops[ooffset + 2] = v;
ops[ooffset + 1] = (void *)5; // -
ops[ooffset] = make_varn(0, 0.0f);
ooffset += 2;
}
offset += inc;
} else {
return 0;
}
}
} }
if (ops[ooffset] == 0) if (ops[ooffset] == 0)
return 0; return 0;
@ -421,10 +414,11 @@ variable *idoexpr(interpreter *interp, const char *line)
break; break;
} }
} }
if (ops[ooffset] == 0)
return 0;
ooffset++;
if (ops[ooffset] == 0) // implicit multiply
ops[ooffset] = (void *)1;
ooffset++;
// skip whitespace // skip whitespace
skipblank(line, eol, &offset); skipblank(line, eol, &offset);
} }

@ -22,15 +22,15 @@ typedef struct {
typedef int (*func_t)(interpreter *); typedef int (*func_t)(interpreter *);
void iinit(interpreter *); void iinit(interpreter *);
void iend(interpreter *it); void iend(interpreter *);
void iskip(interpreter *it); void iskip(interpreter *);
variable *inew_string(interpreter *, const char *, const char *); variable *inew_string(interpreter *, const char *, const char *);
variable *inew_number(interpreter *, const char *, float); variable *inew_number(interpreter *, const char *, float);
variable *inew_cfunc(interpreter *, const char *, func_t); variable *inew_cfunc(interpreter *, const char *, func_t);
int idoline(interpreter *, const char *); int idoline(interpreter *, const char *);
variable *idoexpr(interpreter *interp, const char *line); variable *idoexpr(interpreter *, const char *);
#endif // PARSER_H_ #endif // PARSER_H_

@ -1,15 +1,7 @@
set a "Het\n" set x 42
set b a set eq ".a/a"
print b
#set a 0 solve eq > ans
#do
# print "> " print ans
# gets text print "\n"
# set input "("
# concat input text
# concat input ")"
# expr input a
# print a
# print "\n"
#while (1)

@ -0,0 +1,52 @@
#include <parser.h>
#include <builtins.h>
#include "stack.h"
#include <memory.h>
#include <stdio.h>
//#include <stdlib.h>
#include <string.h>
int s_put(interpreter *it)
{
variable *v = igetarg(it, 0);
if (v->valtype == NUMBER)
printf("%.f", v->value.f);
else
printf("%s", (char *)v->value.p);
return 0;
}
int main(int argc, char **argv)
{
interpreter interp;
if (argc != 2) {
printf("Usage: %s file\n", argv[0]);
return -1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == 0) {
printf("Could not open file: %s\n", argv[1]);
return -1;
}
iinit(&interp);
inew_cfunc(&interp, "print", s_put);
char *line = 0;
unsigned int size;
int result;
while (getline(&line, &size, fp) != -1) {
*strchr(line, '\n') = '\0';
result = idoline(&interp, line);
if (result != 0)
printf("Error: %d\n", result);
}
fclose(fp);
iend(&interp);
return 0;
}

@ -1,6 +1,7 @@
#include "variable.h" #include "variable.h"
#include "parser.h" #include "parser.h"
#include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <memory.h> #include <memory.h>
#include <string.h> #include <string.h>
@ -69,3 +70,66 @@ variable *make_vare(variable *v, const char *expr)
return v; return v;
} }
int try_variable(char **name, const char *text)
{
if (name == 0)
return 0;
int neg = 1;
int i = 0;
if (text[0] == '-') {
neg = -1;
i++;
}
if (!isalpha(text[i]))
return 0;
for (i++; isalnum(text[i]); i++);
int o = (neg < 0);
if (neg < 0)
i--;
*name = (char *)malloc(i + 1);
strncpy(*name, text + o, i);
(*name)[i] = '\0';
return (neg > 0) ? i : -(i + 1);
}
int try_number(variable *v, const char *text)
{
if (v == 0)
return 0;
int decimal = -1;
char valid = 0;
int i = 0;
if (text[0] == '-')
i++;
do {
if (text[i] == '.') {
if (decimal >= 0) {
valid = 0;
break;
}
decimal = i;
} else if (isdigit(text[i])) {
valid |= 1;
} else {
break;
}
} while (text[++i] != '\0');
if (valid == 0)
return 0;
char *buf = (char *)malloc(i + 1);
strncpy(buf, text, i);
buf[i] = '\0';
make_varn(v, strtof(buf, 0));
free(buf);
return i;
}

@ -25,4 +25,7 @@ variable *make_vars(variable *v, const char *s);
variable *make_varf(variable *v, uint8_t fromc, uint32_t func); variable *make_varf(variable *v, uint8_t fromc, uint32_t func);
variable *make_vare(variable *v, const char *e); variable *make_vare(variable *v, const char *e);
int try_number(variable *v, const char *text);
int try_variable(char **name, const char *text);
#endif // VARIABLE_H_ #endif // VARIABLE_H_

Loading…
Cancel
Save