cwal

Check-in [408488e99a]
Login

Check-in [408488e99a]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added whcl decl {varname val var2 val...} syntax.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 408488e99ad6d2f494a3414cbf83d3ab4f3d8839
User & Date: stephan 2022-04-13 08:05:14
Context
2022-04-13
08:07
Annotated a TODO. check-in: 3da74f5b97 user: stephan tags: trunk
08:05
Added whcl decl {varname val var2 val...} syntax. check-in: 408488e99a user: stephan tags: trunk
07:58
Moved the cwal index.md. check-in: ee67cc2e22 user: stephan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to whcl/manual/builtins.md.
200
201
202
203
204
205
206


207

208
209
210
211
212
213
214
that it accepts as few as one arguments, the intent of that use case
being to convert non-strings to strings.

<a id='bic-const'></a>
const
------------------------------------------------------------



Usage: `const varName value|builtin command...`


This is a convenience form of [`decl -const`](#bic-decl).

<a id='bic-continue'></a>
continue
------------------------------------------------------------








>
>
|
>







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
that it accepts as few as one arguments, the intent of that use case
being to convert non-strings to strings.

<a id='bic-const'></a>
const
------------------------------------------------------------

Usages:

- `const varName value|builtin command...`
- `const {varName value var2 value...}`

This is a convenience form of [`decl -const`](#bic-decl).

<a id='bic-continue'></a>
continue
------------------------------------------------------------

244
245
246
247
248
249
250


251

252
253
254
255


256
257
258




259

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277

<a id='bic-decl'></a>
decl
------------------------------------------------------------

See also: [variables][] and [`const`](#bic-const)



Usage: `decl: [-const] varname [value|builtin-command args...]`


Declares a symbolic name as being available for this scope and [all
subsequent sub-scopes which can see into this
one](symbol-resolution.md). If the final argument is the name of a


builtin command then that command is run, passing on any remaining
arguments. That permits declarations to use (e.g.) the `object`,
`array`, and `proc` commands without having to wrap them in `[...]`.




Evaluates to the new value, or `undefined` if no value was provided.


The `-const` flag marks the variable as "constant," meaning it cannot
be reassigned. It is illegal to use this flag without providing a
value. If the value is a container object, constness does not protect
its contents from being modified.

> Sidebar: long story short, the requirement of explicitly declaring
variables instead of using `set` to both declare and assign to
variables is due to significant difference between how TCL and our
scripting engine resolve symbols. We cannot sensibly support
TCL-like usage within this framework.


<a id='bic-decr'></a>
decr
------------------------------------------------------------

Usage: `decr identifier|$var[property] [value=1]`







>
>
|
>



|
>
>
|

|
>
>
>
>
|
>

|
|
|
|


|
|
|
|







247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

<a id='bic-decl'></a>
decl
------------------------------------------------------------

See also: [variables][] and [`const`](#bic-const)

Usages:

- `decl: [-const] varname [value|builtin-command args...]`
- `decl: [-const] {varname value [var2 value2...]}`

Declares a symbolic name as being available for this scope and [all
subsequent sub-scopes which can see into this
one](symbol-resolution.md).

With the first usage, if the final argument is the name of a builtin
command then that command is run, passing on any remaining
arguments. That permits declarations to use (e.g.) the `object`,
`array`, and `proc` commands without having to wrap them in
`[...]`. The `{...}` usage requires matching pairs of var names and
values and does not support commands as values unless they're wrapped
in `[...]`.

The first form evaluates to the new value, or `undefined` if no value
was provided.  The second form evaluates to `undefined`.

The `-const` flag marks the variable(s) as "constant," meaning it/they
cannot be reassigned. It is illegal to use this flag without providing
a value. If the value is a container object, constness does not
protect its contents from being modified.

> Sidebar: long story short, the requirement of explicitly declaring
  variables instead of using `set` to both declare and assign to
  variables is due to significant difference between how TCL and our
  scripting engine handle scopes and resolve symbols. We cannot
  sensibly support TCL-like usage within this framework.


<a id='bic-decr'></a>
decr
------------------------------------------------------------

Usage: `decr identifier|$var[property] [value=1]`
Changes to whcl/manual/index.md.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
--------

Other docs:

- [Building whcl](build.md)
- [Grammar](grammar.md)
  - [Symbol Resolution](symbol-resolution.md).
    \[Potential\] Users need to understand this slightly
    (but not overly) unusual aspect of whcl.
- [Data Types](type-intro.md)
- [Builtin Commands and Values](builtins.md)
- [API Index](api-index.md)
- [whclsh: the whcl shell](whclsh.md)
- [Example scripts](/dir/whcl/unit?ci=trunk) (whcl's own unit tests)
- [Tips and Tricks](tips-tricks.md) for getting the most out of whcl
- [Tokenization and Evaluation Models](t10n.md)







<
<







10
11
12
13
14
15
16


17
18
19
20
21
22
23
--------

Other docs:

- [Building whcl](build.md)
- [Grammar](grammar.md)
  - [Symbol Resolution](symbol-resolution.md).


- [Data Types](type-intro.md)
- [Builtin Commands and Values](builtins.md)
- [API Index](api-index.md)
- [whclsh: the whcl shell](whclsh.md)
- [Example scripts](/dir/whcl/unit?ci=trunk) (whcl's own unit tests)
- [Tips and Tricks](tips-tricks.md) for getting the most out of whcl
- [Tokenization and Evaluation Models](t10n.md)
Changes to whcl/manual/variables.md.
46
47
48
49
50
51
52
















53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

To be written more succintly as:

```whcl
decl o object a b c d
```

















`decl` evaluates to the value it sets, so:

```whcl
assert 1 == [decl x 1]
```

See [this sidebar](builtins.md#builtin-vs-non) for why `decl` can
treat builtins specially in this regard but cannot do the same for
non-builtin commands.


<a id='dereference'></a>
Dereferencing Variables
============================================================

To "dereference" a variable means to extract its referenced value.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|





|
<
<







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75


76
77
78
79
80
81
82

To be written more succintly as:

```whcl
decl o object a b c d
```

> Sidebar: see [this section](builtins.md#builtin-vs-non) for why
  `decl` can treat builtins specially in this regard but cannot do the
  same for non-builtin commands.

When declaring multiple values, this alternate syntax may be simpler:

```whcl
decl {
  X 1
  Y 2
}
```

Noting that that syntax does _not_ support commands (builtin or
otherwise) as values unless they're wrapped in `[...]`.

The "simple" form of `decl` evaluates to the value it sets, so:

```whcl
assert 1 == [decl x 1]
```

The `{...}` syntax always evaluates to `undefined`.




<a id='dereference'></a>
Dereferencing Variables
============================================================

To "dereference" a variable means to extract its referenced value.
Changes to whcl/unit/000-000-basics.whcl.
12
13
14
15
16
17
18
19



20
21


22
23
24
25
26
27
28
29
    abc def

}}} == {abc def}
assert <<<:XX    three spaces    XX == "   three spaces   "
assert {{{:    three spaces    }}} == "   three spaces   "


decl x 1



assert [info is-local x]
assert $x == 1


unset x
assert ![info is-local x]

decl x object {a 1 b 2 c 3}
assert 1 == $x[a]
assert 2 == $x[b]
assert 3 == $x[c]
unset \







|
>
>
>


>
>
|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    abc def

}}} == {abc def}
assert <<<:XX    three spaces    XX == "   three spaces   "
assert {{{:    three spaces    }}} == "   three spaces   "


decl {
    x 1
    y 2
}
assert [info is-local x]
assert $x == 1
assert [info is-local y]
assert 2 == $y
unset x y
assert ![info is-local x]

decl x object {a 1 b 2 c 3}
assert 1 == $x[a]
assert 2 == $x[b]
assert 3 == $x[c]
unset \
Changes to whcl/whcl.c.
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

#define whcl__rescopeS(S,v)                    \
  cwal_value_rescope(&S->cs, v)
#define whcl__rescopeE(E,v)                    \
  whcl__rescopeS(E->scopes.current, v)

cwal_value * whcl_scope_props(whcl_engine * const el,
                               whcl_scope * const sc_){
  whcl_scope * const sc = sc_ ? sc_ : whcl__scope_current(el);
  if(!sc->props){
    sc->props = cwal_new_object_value(el->ec);
    if(!sc->props){WHCL__WARN_OOM; return NULL;}
    whcl__rescopeS(sc, sc->props);
    cwal_value_make_vacuum_proof(sc->props, true);
    cwal_value_prototype_set(sc->props, NULL);







|







443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

#define whcl__rescopeS(S,v)                    \
  cwal_value_rescope(&S->cs, v)
#define whcl__rescopeE(E,v)                    \
  whcl__rescopeS(E->scopes.current, v)

cwal_value * whcl_scope_props(whcl_engine * const el,
                              whcl_scope * const sc_){
  whcl_scope * const sc = sc_ ? sc_ : whcl__scope_current(el);
  if(!sc->props){
    sc->props = cwal_new_object_value(el->ec);
    if(!sc->props){WHCL__WARN_OOM; return NULL;}
    whcl__rescopeS(sc, sc->props);
    cwal_value_make_vacuum_proof(sc->props, true);
    cwal_value_prototype_set(sc->props, NULL);
2404
2405
2406
2407
2408
2409
2410
2411
2412


2413
2414
2415
2416
2417
2418
2419

2420
2421


2422
2423
2424
2425
2426
2427
2428
    //whcl__dump_stok(ct, tok, "key");
    switch(tok->ttype){
      case TOK1_T_BraceGroup:
      case TOK1_T_IdentifierDeref:
      case TOK1_T_ParenGroup:
        rc = whcl__eval_token(el, ct, tok, 0, &key);
        break;
      case TOK1_T_BIC:
      case TOK1_T_BIV:


      case TOK1_T_Identifier:
      case TOK1_T_LiteralNumber:
      case TOK1_T_QuotedString:
      case TOK1_T_SquigglyGroup:
        rc = whcl__create_value2(el, ct, tok, true, &key);
        break;
      default:

        rc = whcl__throw(el, ct, tok, CWAL_RC_TYPE,
                         "Invalid token type for object key.");


        break;
    }
    if(rc || (rc = whcl__holder_push(el, key))) break;
    if((rc = next_t)) break;
    //whcl__dump_stok(ct, tok, "val");
#undef next_t
    switch(whcl_t_is_eox(tok->ttype) ? 0 : tok->ttype){







|
|
>
>
|






>

|
>
>







2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
    //whcl__dump_stok(ct, tok, "key");
    switch(tok->ttype){
      case TOK1_T_BraceGroup:
      case TOK1_T_IdentifierDeref:
      case TOK1_T_ParenGroup:
        rc = whcl__eval_token(el, ct, tok, 0, &key);
        break;
      case TOK1_T_BIV:
      case TOK1_T_Identifier:
        if(tok->subscriptId) goto not_a_key;
        CWAL_SWITCH_FALL_THROUGH;
      case TOK1_T_BIC:
      case TOK1_T_LiteralNumber:
      case TOK1_T_QuotedString:
      case TOK1_T_SquigglyGroup:
        rc = whcl__create_value2(el, ct, tok, true, &key);
        break;
      default:
        not_a_key:
        rc = whcl__throw(el, ct, tok, CWAL_RC_TYPE,
                         "Invalid token type (%s) for object key.",
                         tok->subscriptId
                         ? "property access" : tok1_t_cstr(tok->ttype));
        break;
    }
    if(rc || (rc = whcl__holder_push(el, key))) break;
    if((rc = next_t)) break;
    //whcl__dump_stok(ct, tok, "val");
#undef next_t
    switch(whcl_t_is_eox(tok->ttype) ? 0 : tok->ttype){
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174

3175
3176
3177
3178
3179
3180
3181
                            whcl_stoken_cstr(args->ct, tArg, NULL, false));
        goto end;
      }
      assert(foundIn);
      break;
    default:
      whcl__script_errtoken_set(args->ct, tArg);
      return whcl_err_throw(args->el, CWAL_RC_TYPE,
                            "Invalid token type (%s) for '%s' command key.",
                            tok1_t_cstr(tArg->ttype),
                            bic->name);

  }
  assert(0==rc);
  if(!crv){
      crv = cwal_new_integer(args->el->ec, 1)/*does not allocate/cannot fail*/;
  }
  rc = whcl__values_addsub(args->el, TOK1_T_BIC_incr==bic->ttype,
                           value, crv, &newV);







|
|
|
|
>







3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
                            whcl_stoken_cstr(args->ct, tArg, NULL, false));
        goto end;
      }
      assert(foundIn);
      break;
    default:
      whcl__script_errtoken_set(args->ct, tArg);
      rc = whcl_err_throw(args->el, CWAL_RC_TYPE,
                          "Invalid token type (%s) for '%s' command key.",
                          tok1_t_cstr(tArg->ttype),
                          bic->name);
      goto end;
  }
  assert(0==rc);
  if(!crv){
      crv = cwal_new_integer(args->el->ec, 1)/*does not allocate/cannot fail*/;
  }
  rc = whcl__values_addsub(args->el, TOK1_T_BIC_incr==bic->ttype,
                           value, crv, &newV);
3194
3195
3196
3197
3198
3199
3200
































































































































3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
  }
  end:
  if(lhs) whcl__dotop_set(args->el, NULL, NULL, NULL);
  whcl__holder_truncate(args->el, holdLen, NULL);
  return rc;
}

































































































































/** Handler for the decl and const commands:

    - `decl [-const] name [value]|builtin command`
    - `const name [value]|builtin command`

    Noting that:

    - `-const` and `const` require a value.

    Result value is that of the declared value (defaulting
    to the undefined value).
 */
static int whcl__bic_f_decl(whcl__bic const * const bic,
                            whcl__args const * const args,
                            cwal_value **rv){







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|


<



|







3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337

3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
  }
  end:
  if(lhs) whcl__dotop_set(args->el, NULL, NULL, NULL);
  whcl__holder_truncate(args->el, holdLen, NULL);
  return rc;
}

/**
   Helper for `decl`:

   decl [-const] {
     key val
     key val...
   }

   Resolves to `undefined`.

   TODO:

   - Add support for `set` as well. That requires a few changes,
   e.g. the ability to have x.y as a key. The 4th arg must be true
   for decl and false for set.

   - Consider adding support for commands in the value positions,
   consuming until EOL/EOF.

   Returns blah blah blah and ownership is blah blah blah. You know
   the drill.
*/
static int whcl__decl_read_object(whcl_engine * const el,
                                  whcl_script * ct,
                                  whcl_stoken const * tok,
                                  bool isDecl, bool isConst){
  int rc = 0;
  cwal_size_t const holdLen = whcl__holder_len(el);
  whcl_script * const oldScript = el->ct;
  whcl_scope * const scel = whcl__scope_current(el);
  cwal_value * const props = whcl_scope_props(el, scel);
  whcl_script sub = whcl__script_empty;
  assert(TOK1_T_SquigglyGroup == tok->ttype);
  if(!props) return CWAL_RC_OOM;
  whcl__stoken_set(ct, tok);
  rc = whcl__script_sub_from_group(ct, &sub, true);
  if(rc) return rc;
  el->ct = ct;
  ct = &sub;
  /* Process the object as a list of key/value pairs... */
#define next_t whcl__next_token_no_eol(ct, &tok)
  for(int i = 0; true; ++i ){
    cwal_value * key = NULL;
    cwal_value * val = NULL;
    whcl_stoken const * tKey;
    rc = next_t;
    if(rc || whcl_t_is_eox(tok->ttype)) break;
    cwal_size_t const preKeyLen = whcl__holder_len(el);
    switch(tok->ttype){
#if 0
      /* TODO: allow for `set` but not `decl`: */
      case TOK1_T_BraceGroup:
      case TOK1_T_IdentifierDeref:
      case TOK1_T_ParenGroup:
        rc = whcl__eval_token(el, ct, tok, 0, &key);
        break;
      case TOK1_T_LiteralNumber:
      case TOK1_T_QuotedString:
      case TOK1_T_SquigglyGroup:
#endif
      case TOK1_T_BIV:
      case TOK1_T_Identifier:
        if(tok->subscriptId) goto not_a_key;
        CWAL_SWITCH_FALL_THROUGH;
      case TOK1_T_BIC:
        rc = whcl__create_value2(el, ct, tok, true, &key);
        break;
      /* TODO: handle keys with subscriptId (property access)
         for isDecl==false (SET but not DECL). */
      default:
        not_a_key:
        rc = whcl__throw(el, ct, tok, CWAL_RC_TYPE,
                         "Invalid token type (%s) for a `%s` key.",
                         tok->subscriptId
                         ? "property access" : tok1_t_cstr(tok->ttype),
                         isDecl ? "decl" : "set");
        break;
    }
    if(rc || (rc = whcl__holder_push(el, key))) break;
    cwal_type_id const keyTypeID = cwal_value_type_id(key);
    switch(keyTypeID){
      case CWAL_TYPE_STRING: break;
      default:
        rc = whcl__throw(el, ct, tok, CWAL_RC_TYPE,
                         "Invalid type (%s) for var name.",
                         cwal_type_id_name(keyTypeID));
        break;
    }
    tKey = tok;
    if(rc || (rc = next_t)) break;
#undef next_t
    switch(whcl_t_is_eox(tok->ttype) ? 0 : tok->ttype){
      case 0:
        rc = whcl_err_throw(el, CWAL_SCR_SYNTAX,
                            "Expecting matching key/value pairs.");
        /* We "could" simply default to undefined for the final value
           when isDecl==true but that seems likely to lead to silent
           misuse and downstream confusion. */
        break;
      default:
        rc = whcl__eval_token(el, ct, tok, 0, &val);
        if(0==rc && !val) val = cwal_value_undefined();
        break;
    }
    if(rc || (rc = whcl__holder_push(el, val))) break;
    whcl__script_errtoken_set(ct, tok);
    if(isDecl && whcl_get_v(el, props, key)){
      cwal_size_t nKey = 0;
      char const * zKey = cwal_value_get_cstr(key, &nKey);
      rc = whcl__throw(el, ct, tKey, CWAL_RC_ALREADY_EXISTS,
                       "Already declared in this scope: %.*s",
                       (int)nKey, zKey);
      break;
    }
    cwal_ref(key); cwal_ref(val);
    rc = whcl_set_with_flags_v(el, props, key,
                               val ? val : cwal_value_undefined(),
                               isConst ? CWAL_VAR_F_CONST : 0);
    cwal_unref(key); cwal_unref(val);
    whcl__holder_truncate(el, preKeyLen, NULL);
    if(rc) break;
  }
  whcl__script_finalize(&sub);
  el->ct = oldScript;
  whcl__holder_truncate(el, holdLen, NULL);
  return rc;
}

/** Handler for the decl command:

    - `decl [-const] name [value]|builtin command`


    Noting that:

    - `-const` requires a value.

    Result value is that of the declared value (defaulting
    to the undefined value).
 */
static int whcl__bic_f_decl(whcl__bic const * const bic,
                            whcl__args const * const args,
                            cwal_value **rv){
3238
3239
3240
3241
3242
3243
3244









3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
      goto end;
    }
    /* i wonder if it might be interesting to add -unique and create
       a unique value with an optional wrapped value. */
  }
  if((rc = whcl__args_ncheck(args, ndx, 1 + doConst))) goto end;
  tName = args->argv[ndx++];









  whcl__stoken_set(args->ct, tName);
  if(whcl__ttype_is_biv(tName->ttype)){
    //whcl__biv_search_t(args->ct, tName)){
    rc = whcl_err_throw(el, CWAL_RC_ALREADY_EXISTS,
                        "Variable name collides with a "
                        "builtin value: %.*s",
                        (int)tName->length,
                        whcl_stoken_cstr(args->ct, tName, NULL, false));
    goto end;
  }else if(TOK1_T_Identifier!=tName->ttype){
    rc = whcl_err_throw(el, CWAL_RC_MISUSE,
                        "Invalid variable name: %.*s",
                        (int)tName->length,
                        whcl_stoken_cstr(args->ct, tName, NULL, false));
    goto end;
  }
  if(ndx==args->argc) xv = cwal_value_undefined();
  /* If we have a BIC, call it. This is primarily a convenience
     to enable: decl x proc {} ...

     Instead of: decl x [proc ...]







>
>
>
>
>
>
>
>
>



|
|
|
|
|


|
|
|
|







3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
      goto end;
    }
    /* i wonder if it might be interesting to add -unique and create
       a unique value with an optional wrapped value. */
  }
  if((rc = whcl__args_ncheck(args, ndx, 1 + doConst))) goto end;
  tName = args->argv[ndx++];
  if(TOK1_T_SquigglyGroup==tName->ttype){
    if(args->argv[ndx]){
      rc = whcl__throw(el, args->ct, args->argv[ndx], CWAL_SCR_SYNTAX,
                       "Extra arguments after {...}.");
      goto end;
    }
    rc = whcl__decl_read_object(args->el, args->ct, tName, true, doConst);
    goto end;
  }  
  whcl__stoken_set(args->ct, tName);
  if(whcl__ttype_is_biv(tName->ttype)){
    //whcl__biv_search_t(args->ct, tName)){
    rc = whcl__throw(el, args->ct, tName, CWAL_RC_ALREADY_EXISTS,
                     "Variable name collides with a "
                     "builtin value: %.*s",
                     (int)tName->length,
                     whcl_stoken_cstr(args->ct, tName, NULL, false));
    goto end;
  }else if(TOK1_T_Identifier!=tName->ttype){
    rc = whcl__throw(el, args->ct, tName, CWAL_RC_MISUSE,
                     "Invalid variable name: %.*s",
                     (int)tName->length,
                     whcl_stoken_cstr(args->ct, tName, NULL, false));
    goto end;
  }
  if(ndx==args->argc) xv = cwal_value_undefined();
  /* If we have a BIC, call it. This is primarily a convenience
     to enable: decl x proc {} ...

     Instead of: decl x [proc ...]
4606
4607
4608
4609
4610
4611
4612
4613
4614

4615
4616
4617
4618
4619
4620
4621
   "[-noscope] [varname] {body}"},
  {"concat",   T(concat),    1, -1,  BIC(concat), "[args...]"},
  {"const",    T(const),     2, -1,  BIC(decl),
               "varname value...|builtin-command args..."},
  {"continue", T(continue),  0, 0,   BIC(brc), ""},
  {"__debug",  T(__debug),   1, 1,   BIC(eval), "{code block}"},
  {"decl",     T(decl),      1, -1,  BIC(decl),
               "[-const] varname "
               "[value...|builtin-command args...]"},

  {"decr",     T(decr),      1, 2,   BIC(crement),
               "varname|deref[key] [by-value]"},
  {"define",   T(define),    2, 2,   DUMMY, "identifier value"},
  {"do",       T(do),        3, 3,   BIC(dowhile),
               "{BODY} while {EXPR}"},
  {"echo",     T(echo),      0, -1,  BIC(echo), "[-n] [args...]"},
  {"eval",     T(eval),      1, 3,   BIC(eval),







|
|
>







4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
   "[-noscope] [varname] {body}"},
  {"concat",   T(concat),    1, -1,  BIC(concat), "[args...]"},
  {"const",    T(const),     2, -1,  BIC(decl),
               "varname value...|builtin-command args..."},
  {"continue", T(continue),  0, 0,   BIC(brc), ""},
  {"__debug",  T(__debug),   1, 1,   BIC(eval), "{code block}"},
  {"decl",     T(decl),      1, -1,  BIC(decl),
               "[-const] varname [value...|builtin-command args...] "
               "| {varName value var2 value...}"
  },
  {"decr",     T(decr),      1, 2,   BIC(crement),
               "varname|deref[key] [by-value]"},
  {"define",   T(define),    2, 2,   DUMMY, "identifier value"},
  {"do",       T(do),        3, 3,   BIC(dowhile),
               "{BODY} while {EXPR}"},
  {"echo",     T(echo),      0, -1,  BIC(echo), "[-n] [args...]"},
  {"eval",     T(eval),      1, 3,   BIC(eval),