outside the if, the variables in the different branches are distinct
and can be of different types.
-Determining the types of all variables early is important for
-processing command line arguments. These can be assigned to any of
-several types of variable, but we must first know the correct type so
-any required conversion can happen. If a variable is associated with
-a command line argument but no type can be interpreted (e.g. the
-variable is only ever used in a `print` statement), then the type is
-set to 'string'.
-
Undeclared names may only appear in "use" statements and "case" expressions.
These names are given a type of "label" and a unique value.
This allows them to fill the role of a name in an enumerated type, which
### Types
Values come in a wide range of types, with more likely to be added.
-Each type needs to be able to parse and print its own values (for
-convenience at least) as well as to compare two values, at least for
-equality and possibly for order. For now, values might need to be
-duplicated and freed, though eventually such manipulations will be
-better integrated into the language.
+Each type needs to be able to print its own values (for convenience at
+least) as well as to compare two values, at least for equality and
+possibly for order. For now, values might need to be duplicated and
+freed, though eventually such manipulations will be better integrated
+into the language.
Rather than requiring every numeric type to support all numeric
operations (add, multiple, etc), we allow types to be able to present
struct type *next;
int size, align;
void (*init)(struct type *type, struct value *val);
- int (*parse)(struct type *type, char *str, struct value *val);
void (*print)(struct type *type, struct value *val);
void (*print_type)(struct type *type, FILE *f);
int (*cmp_order)(struct type *t1, struct type *t2,
printf("*Unknown*"); // NOTEST
}
- static int parse_value(struct type *type, char *arg,
- struct value *val)
- {
- if (type && type->parse)
- return type->parse(type, arg, val);
- return 0; // NOTEST
- }
-
static struct value *val_alloc(struct type *t, struct value *init)
{
struct value *ret;
static int value_cmp(struct type *tl, struct type *tr,
struct value *left, struct value *right);
static void print_value(struct type *type, struct value *v);
- static int parse_value(struct type *type, char *arg, struct value *val);
###### free context types
return require == have;
}
-When assigning command line arguments to variables, we need to be able
-to parse each type from a string.
-
###### includes
#include <gmp.h>
#include "parse_string.h"
}
}
- static int _parse_value(struct type *type, char *arg, struct value *val)
- {
- struct text tx;
- int neg = 0;
- char tail[3] = "";
-
- switch(type->vtype) {
- case Vlabel: // NOTEST
- case Vnone: // NOTEST
- return 0; // NOTEST
- case Vstr:
- val->str.len = strlen(arg);
- val->str.txt = malloc(val->str.len);
- memcpy(val->str.txt, arg, val->str.len);
- break;
- case Vnum:
- if (*arg == '-') {
- neg = 1;
- arg++;
- }
- tx.txt = arg; tx.len = strlen(tx.txt);
- if (number_parse(val->num, tail, tx) == 0)
- mpq_init(val->num);
- else if (neg)
- mpq_neg(val->num, val->num);
- if (tail[0]) {
- printf("Unsupported suffix: %s\n", arg);
- return 0;
- }
- break;
- case Vbool:
- if (strcasecmp(arg, "true") == 0 ||
- strcmp(arg, "1") == 0)
- val->bool = 1;
- else if (strcasecmp(arg, "false") == 0 ||
- strcmp(arg, "0") == 0)
- val->bool = 0;
- else {
- printf("Bad bool: %s\n", arg);
- return 0;
- }
- break;
- }
- return 1;
- }
-
static void _free_value(struct type *type, struct value *v);
static struct type base_prototype = {
.init = _val_init,
- .parse = _parse_value,
.print = _print_value,
.cmp_order = _value_cmp,
.cmp_eq = _value_cmp,
right = interp_exec(b->right, &rvtype);
rtype = Tstr;
rvtype = Tnum;
- char *str = strndup(right.str.txt, right.str.len);
- parse_value(rvtype, str, &rv);
- free(str);
+
+ struct text tx = right.str;
+ char tail[3];
+ int neg = 0;
+ if (tx.txt[0] == '-') {
+ neg = 1;
+ tx.txt++;
+ tx.len--;
+ }
+ if (number_parse(rv.num, tail, tx) == 0)
+ mpq_init(rv.num);
+ else if (neg)
+ mpq_neg(rv.num, rv.num);
+ if (tail[0])
+ printf("Unsupported suffix: %.*s\n", tx.len, tx.txt);
+
break;
###### value functions
v->var->val = vl;
}
free_value(v->var->type, vl);
- if (!parse_value(v->var->type, argv[0], vl))
- exit(1);
+ vl->str.len = strlen(argv[0]);
+ vl->str.txt = malloc(vl->str.len);
+ memcpy(vl->str.txt, argv[0], vl->str.len);
argv++;
}
v = interp_exec(p->right, &vtype);