c3c icon indicating copy to clipboard operation
c3c copied to clipboard

feature request: $nextcase and $break in compile-time $switch

Open NotsoanoNimus opened this issue 5 months ago • 5 comments

A fallthrough and break option for compile-time switch statements should be included to control flow with compile-time values.

e.g. ...

$switch ($ct_argstype[($argidx / 3)]) :
    $case OptionArgType.EXPLICIT_NONE: $break;
    $case OptionArgType.FLAG: *($vaarg[$argidx + 2]) = true;
    $case OptionArgType.INCREMENTAL: *($vaarg[$argidx + 2]) = *($vaarg[$argidx + 2]) + 1;
    $case OptionArgType.OPTIONAL_ARGUMENT:
        if (null != opt::arg.ptr) break CT_SWITCH;
        $nextcase;
    $case OptionArgType.REQUIRED_ARGUMENT:
        if (null == opt::arg.ptr || !opt::arg.len) return MISSING_ARGUMENT?;
        // etc...
$endswitch

NotsoanoNimus avatar Jul 07 '25 15:07 NotsoanoNimus

As we talked about before on the discord, this is currently not planned. I would like to keep the compile time meta language to be as simplistic as possible, which means that sometimes useful features are omitted. Possibly we could add $goto and $label FOO though, if people have important use-cases for it. But my thought is that if it is complex enough then maybe compile time code isn't the right place for it, and instead one could then use $exec and project exec to generate that code?

lerno avatar Jul 09 '25 09:07 lerno

I think that's entirely sensible, given the extra complexities that compile-time evaluation can introduce as well as the added sluggishness to c3c, which I understand is important to limit carefully.

I do believe that $goto and $label will actually resolve all related flow control meta-language feature requests if you're able to implement them. You could well consider anyone's reasons for $nextcase, $break, $continue, etc. as all use-cases solvable by those two statements. This also removes the need for some of the more hacky solutions around labeled runtime if/while LABEL: (true) type statements with compile-time-wrapped break/continue LABEL statements.

And then with $goto + $label, questions of $exec could still remain a separate discussion and have a less coupled set of use-cases.

NotsoanoNimus avatar Jul 09 '25 15:07 NotsoanoNimus

So something like:

$for $i = 0; $i < 10; $i++:
  $if $i > CONST:
    $goto LABEL;
  $endif
$endfor
$label LABEL:

lerno avatar Oct 10 '25 12:10 lerno

$switch $a:
  $case int:
     $b[$j++] = 1;
     $goto NEXT;
  $case double:
     $label NEXT:
     $b[$j++] = foo();
$endswitch;

lerno avatar Oct 10 '25 12:10 lerno

There are problems with the semantics of this. Consider the following two:

$for var $i = 0; $i < 3; $i++:
  {
    int a = 0;
    $if @foo($i) == 0:
      $break; // Break inside a runtime block
    $endif
    test(&a);
  }
$endfor
$if @foo(BAR):
  $goto $FOO; // Jumping into a loop
$endif
int x;
$for var $i = 0; $i < 3; $i++:
$FOO:
  test();
$endfor

Both have questionable semantics. Even this is not straightforward:

$switch @foo($i):
  $case 1:
     foo();
     $goto $BAR;
  $case 2:
     baz();
$BAR:
     bar();
$endswitch

If $goto can only jump OUT of a compile time scope, and to the beginning of a $case, then it would more straightforward. But the complexity of it makes me wonder whether it's sufficiently important.

lerno avatar Nov 03 '25 13:11 lerno