]> ocean-lang.org Git - ocean/blobdiff - csrc/oceani.mdc
oceani: drop parse_value method for types.
[ocean] / csrc / oceani.mdc
index 520212be6d144365a586638bf695098689460058..e3dc493d7fb1b787ba46cca80fb0724d43ef1560 100644 (file)
@@ -287,14 +287,6 @@ consistent across all the branches.  When the variable is not used
 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
@@ -407,11 +399,11 @@ various entities.
 ### 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
@@ -437,7 +429,6 @@ Named type are stored in a simple linked list.  Objects of each type are
                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,
@@ -541,14 +532,6 @@ Named type are stored in a simple linked list.  Objects of each type are
                        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;
@@ -574,7 +557,6 @@ Named type are stored in a simple linked list.  Objects of each type are
        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
 
@@ -627,9 +609,6 @@ A separate function encoding these cases will simplify some code later.
                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"
@@ -747,57 +726,10 @@ to parse each type from a string.
                }
        }
 
-       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,
@@ -2772,9 +2704,14 @@ expression operator, and the `CMPop` non-terminal will match one of them.
 
 ### Expressions: The rest
 
-The remaining expressions with the highest precedence are arithmetic and
-string concatenation.  String concatenation (`++`) has the same
-precedence as multiplication and division, but lower than the uniary.
+The remaining expressions with the highest precedence are arithmetic,
+string concatenation, and string conversion.  String concatenation
+(`++`) has the same precedence as multiplication and division, but lower
+than the uniary.
+
+String conversion is a temporary feature until I get a better type
+system.  `$` is a prefix operator which expects a string and returns
+a number.
 
 `+` and `-` are both infix and prefix operations (where they are
 absolute value and negation).  These have different operator names.
@@ -2788,12 +2725,13 @@ should only insert brackets were needed for precedence.
        Times, Divide, Rem,
        Concat,
        Absolute, Negate,
+       StringConv,
        Bracket,
 
 ###### expr precedence
        $LEFT + - Eop
        $LEFT * / % ++ Top
-       $LEFT Uop
+       $LEFT Uop $
        $TERM ( )
 
 ###### expression grammar
@@ -2834,6 +2772,7 @@ should only insert brackets were needed for precedence.
 
        Uop ->    + ${ $0.op = Absolute; }$
                | - ${ $0.op = Negate; }$
+               | $ ${ $0.op = StringConv; }$
 
        Top ->    * ${ $0.op = Times; }$
                | / ${ $0.op = Divide; }$
@@ -2862,14 +2801,15 @@ should only insert brackets were needed for precedence.
                if (bracket) printf(")");
                break;
        case Absolute:
-               if (bracket) printf("(");
-               printf("+");
-               print_exec(b->right, indent, bracket);
-               if (bracket) printf(")");
-               break;
        case Negate:
+       case StringConv:
                if (bracket) printf("(");
-               printf("-");
+               switch (b->op) {
+               case Absolute:   fputs("+", stdout); break;
+               case Negate:     fputs("-", stdout); break;
+               case StringConv: fputs("$", stdout); break;
+               default: abort();       // NOTEST
+               }                       // NOTEST
                print_exec(b->right, indent, bracket);
                if (bracket) printf(")");
                break;
@@ -2906,6 +2846,15 @@ should only insert brackets were needed for precedence.
                                   Tstr, rules, type);
                return Tstr;
 
+       case StringConv:
+               /* op must be string, result is number */
+               propagate_types(b->left, c, ok, Tstr, 0);
+               if (!type_compat(type, Tnum, 0))
+                       type_err(c,
+                         "error: Can only convert string to number, not %1",
+                               prog, type, 0, NULL);
+               return Tnum;
+
        case Bracket:
                return propagate_types(b->right, c, ok, type, 0);
 
@@ -2963,6 +2912,27 @@ should only insert brackets were needed for precedence.
                rvtype = Tstr;
                rv.str = text_join(left.str, right.str);
                break;
+       case StringConv:
+               right = interp_exec(b->right, &rvtype);
+               rtype = Tstr;
+               rvtype = Tnum;
+
+               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
 
@@ -4209,8 +4179,9 @@ analysis is a bit more interesting at this level.
                                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);
@@ -4248,11 +4219,13 @@ things which will likely grow as the languages grows.
                name:string
                alive:Boolean
 
-       program A B:
+       program Astr Bstr:
                print "Hello World, what lovely oceans you have!"
                print "Are there", five, "?"
                print pi, pie, "but", cake
 
+               A := $Astr; B := $Bstr
+
                /* When a variable is defined in both branches of an 'if',
                 * and used afterwards, the variables are merged.
                 */