buildStdModule function

Module buildStdModule()

Builds the universal std base module with language-agnostic types and functions.

Implementation

Module buildStdModule() {
  final module = Module()
    ..name = 'std'
    ..description =
        'Universal standard library base module. Every function here '
        'represents a language-agnostic operation that all target languages '
        'implement natively. Types use protobuf descriptors so they map to '
        'every target language.';

  // ============================================================
  // Types (input message types for universal base functions)
  // ============================================================

  module.typeDefs.addAll(
    <google.DescriptorProto>[
      _type('BinaryInput', [_exprField('left', 1), _exprField('right', 2)]),
      _type('UnaryInput', [_exprField('value', 1)]),
      _type('PrintInput', [_stringField('message', 1)]),
      _type('IfInput', [
        _exprField('condition', 1),
        _exprField('then', 2),
        _exprField('else', 3),
        _stringField('case_pattern', 4),
      ]),
      _type('ForInput', [
        _exprField('init', 1),
        _exprField('condition', 2),
        _exprField('update', 3),
        _exprField('body', 4),
      ]),
      _type('ForInInput', [
        _stringField('variable', 1),
        _stringField('variable_type', 2),
        _exprField('iterable', 3),
        _exprField('body', 4),
      ]),
      _type('WhileInput', [_exprField('condition', 1), _exprField('body', 2)]),
      _type('DoWhileInput', [
        _exprField('body', 1),
        _exprField('condition', 2),
      ]),
      _type('SwitchInput', [
        _exprField('subject', 1),
        _exprListField('cases', 2),
      ]),
      _type('SwitchCase', [
        _exprField('value', 1),
        _boolField('is_default', 2),
        _exprField('body', 3),
        _stringField('pattern', 4),
      ]),
      _type('TryInput', [
        _exprField('body', 1),
        _exprListField('catches', 2),
        _exprField('finally', 3),
      ]),
      _type('CatchClause', [
        _stringField('type', 1),
        _stringField('variable', 2),
        _stringField('stack_trace', 3),
        _exprField('body', 4),
      ]),
      _type('AssertInput', [
        _exprField('condition', 1),
        _exprField('message', 2),
      ]),
      _type('AssignInput', [
        _exprField('target', 1),
        _exprField('value', 2),
        _stringField('op', 3),
      ]),
      _type('IndexInput', [_exprField('target', 1), _exprField('index', 2)]),
      _type('TypeCheckInput', [
        _exprField('value', 1),
        _stringField('type', 2),
      ]),
      _type('BreakInput', [_stringField('label', 1)]),
      _type('ContinueInput', [_stringField('label', 1)]),
      _type('ReturnInput', [_exprField('value', 1)]),
      _type('GotoInput', [_stringField('label', 1)]),
      _type('LabelInput', [_stringField('name', 1), _exprField('body', 2)]),

      // --- String operation input types ---
      _type('StringSubstringInput', [
        _exprField('value', 1),
        _exprField('start', 2),
        _exprField('end', 3),
      ]),
      _type('StringReplaceInput', [
        _exprField('value', 1),
        _exprField('from', 2),
        _exprField('to', 3),
      ]),
      _type('StringRepeatInput', [
        _exprField('value', 1),
        _exprField('count', 2),
      ]),
      _type('StringPadInput', [
        _exprField('value', 1),
        _exprField('width', 2),
        _exprField('padding', 3),
      ]),

      // --- Math input types ---
      _type('CompareToInput', [_exprField('value', 1), _exprField('other', 2)]),
      // Shared by to_string_as_fixed / to_string_as_exponential (both take
      // `digits`) and to_string_as_precision (`precision`), mirroring how
      // ListInput/MapInput serve a family of related operations.
      _type('NumFormatInput', [
        _exprField('value', 1),
        _exprField('digits', 2),
        _exprField('precision', 3),
      ]),
      _type('MathClampInput', [
        _exprField('value', 1),
        _exprField('min', 2),
        _exprField('max', 3),
      ]),
    ].map(
      (d) => TypeDefinition()
        ..name = d.name
        ..descriptor = d,
    ),
  );

  // ============================================================
  // Functions — universal, language-agnostic
  // ============================================================

  module.functions.addAll([
    // --- I/O ---
    _fn('print', 'PrintInput', '', 'Print to stdout: print(message)'),

    // --- Arithmetic ---
    _fn('add', 'BinaryInput', '', 'Addition: left + right'),
    _fn('subtract', 'BinaryInput', '', 'Subtraction: left - right'),
    _fn('multiply', 'BinaryInput', '', 'Multiplication: left * right'),
    _fn('divide', 'BinaryInput', '', 'Integer division: left ~/ right'),
    _fn('divide_double', 'BinaryInput', '', 'Double division: left / right'),
    _fn('modulo', 'BinaryInput', '', 'Modulo: left % right'),
    _fn('negate', 'UnaryInput', '', 'Unary negation: -value'),

    // --- Comparison ---
    _fn('equals', 'BinaryInput', '', 'Equality: left == right'),
    _fn('not_equals', 'BinaryInput', '', 'Inequality: left != right'),
    _fn('less_than', 'BinaryInput', '', 'Less than: left < right'),
    _fn('greater_than', 'BinaryInput', '', 'Greater than: left > right'),
    _fn('lte', 'BinaryInput', '', 'Less or equal: left <= right'),
    _fn('gte', 'BinaryInput', '', 'Greater or equal: left >= right'),

    // --- Logical ---
    _fn('and', 'BinaryInput', '', 'Logical AND: left && right'),
    _fn('or', 'BinaryInput', '', 'Logical OR: left || right'),
    _fn('not', 'UnaryInput', '', 'Logical NOT: !value'),

    // --- Bitwise ---
    _fn('bitwise_and', 'BinaryInput', '', 'Bitwise AND: left & right'),
    _fn('bitwise_or', 'BinaryInput', '', 'Bitwise OR: left | right'),
    _fn('bitwise_xor', 'BinaryInput', '', 'Bitwise XOR: left ^ right'),
    _fn('bitwise_not', 'UnaryInput', '', 'Bitwise NOT: ~value'),
    _fn('left_shift', 'BinaryInput', '', 'Left shift: left << right'),
    _fn('right_shift', 'BinaryInput', '', 'Right shift: left >> right'),
    _fn(
      'unsigned_right_shift',
      'BinaryInput',
      '',
      'Unsigned right shift: left >>> right',
    ),

    // --- Increment/Decrement ---
    _fn('pre_increment', 'UnaryInput', '', 'Prefix increment: ++value'),
    _fn('pre_decrement', 'UnaryInput', '', 'Prefix decrement: --value'),
    _fn('post_increment', 'UnaryInput', '', 'Postfix increment: value++'),
    _fn('post_decrement', 'UnaryInput', '', 'Postfix decrement: value--'),

    // --- String & Conversion ---
    _fn(
      'concat',
      'BinaryInput',
      '',
      'String concatenation: left + right (strings)',
    ),
    _fn('to_string', 'UnaryInput', '', 'Convert to string: value.toString()'),
    _fn('length', 'UnaryInput', '', 'Get length: value.length'),
    _fn('int_to_string', 'UnaryInput', '', 'Int to string: value.toString()'),
    _fn(
      'double_to_string',
      'UnaryInput',
      '',
      'Double to string: value.toString()',
    ),
    _fn(
      'string_to_int',
      'UnaryInput',
      '',
      'Parse int from string: int.parse(value)',
    ),
    _fn(
      'string_to_double',
      'UnaryInput',
      '',
      'Parse double from string: double.parse(value)',
    ),
    _fn('to_double', 'UnaryInput', '', 'To double: value.toDouble()'),
    _fn('to_int', 'UnaryInput', '', 'To int: value.toInt()'),
    _fn(
      'compare_to',
      'CompareToInput',
      '',
      'Three-way compare: value.compareTo(other)',
    ),
    _fn(
      'to_string_as_fixed',
      'NumFormatInput',
      '',
      'Fixed-point string: value.toStringAsFixed(digits)',
    ),
    _fn(
      'to_string_as_exponential',
      'NumFormatInput',
      '',
      'Exponential string: value.toStringAsExponential([digits])',
    ),
    _fn(
      'to_string_as_precision',
      'NumFormatInput',
      '',
      'Precision string: value.toStringAsPrecision(precision)',
    ),

    // --- Null safety ---
    _fn('null_coalesce', 'BinaryInput', '', 'Null coalescing: left ?? right'),
    _fn('null_check', 'UnaryInput', '', 'Null assertion: value!'),

    // --- Control flow ---
    _fn('if', 'IfInput', '', 'Conditional: if (cond) { then } else { else }'),
    _fn(
      'for',
      'ForInput',
      '',
      'C-style for loop: for (init; cond; update) { body }',
    ),
    _fn(
      'for_in',
      'ForInInput',
      '',
      'For-in loop: for (var x in iterable) { body }',
    ),
    _fn('while', 'WhileInput', '', 'While loop: while (cond) { body }'),
    _fn(
      'do_while',
      'DoWhileInput',
      '',
      'Do-while loop: do { body } while (cond)',
    ),
    _fn(
      'switch',
      'SwitchInput',
      '',
      'Switch statement: switch (subj) { case ... }',
    ),

    // --- Error handling ---
    _fn(
      'try',
      'TryInput',
      '',
      'Try-catch-finally: try { } catch (e) { } finally { }',
    ),
    _fn('throw', 'UnaryInput', '', 'Throw exception: throw value'),
    _fn('rethrow', '', '', 'Rethrow current exception: rethrow'),

    // --- Assertions ---
    _fn('assert', 'AssertInput', '', 'Debug assertion: assert(cond, msg)'),

    // --- Flow control ---
    _fn('return', 'ReturnInput', '', 'Return from function: return value'),
    _fn('break', 'BreakInput', '', 'Break from loop/switch: break [label]'),
    _fn(
      'continue',
      'ContinueInput',
      '',
      'Continue to next iteration: continue [label]',
    ),

    // --- goto / labels ---
    _fn('goto', 'GotoInput', '', 'Jump to label: goto label_name'),
    _fn(
      'label',
      'LabelInput',
      '',
      'Define a label point: label_name: { body }',
    ),

    // --- Generators & async ---
    _fn('yield', 'UnaryInput', '', 'Yield from generator: yield value'),
    _fn('await', 'UnaryInput', '', 'Await a future: await value'),

    // --- Assignment ---
    _fn(
      'assign',
      'AssignInput',
      '',
      'Assignment (simple or compound): target = value, target += value',
    ),

    // --- Type operations ---
    _fn('is', 'TypeCheckInput', '', 'Type test: value is Type'),
    _fn('is_not', 'TypeCheckInput', '', 'Negated type test: value is! Type'),
    _fn('as', 'TypeCheckInput', '', 'Type cast: value as Type'),
    _fn(
      'type_of',
      'UnaryInput',
      '',
      'Runtime type name: value.runtimeType.toString() / JS typeof. '
          'Returns the canonical base type name (int, double, String, bool, '
          "List, Map, Set, Function, Null, or a user class's short name) "
          'with generic type arguments dropped and any module prefix stripped.',
    ),

    // --- Indexing ---
    _fn('index', 'IndexInput', '', 'Index access: target[index]'),

    // --- Strings (pure manipulation, no I/O, universal) ---
    _fn('string_length', 'UnaryInput', '', 'String length: value.length'),
    _fn('string_is_empty', 'UnaryInput', '', 'Is string empty: value.isEmpty'),
    _fn('string_concat', 'BinaryInput', '', 'String concat: left + right'),
    _fn(
      'string_contains',
      'BinaryInput',
      '',
      'String contains: left.contains(right)',
    ),
    _fn(
      'string_starts_with',
      'BinaryInput',
      '',
      'Starts with: left.startsWith(right)',
    ),
    _fn(
      'string_ends_with',
      'BinaryInput',
      '',
      'Ends with: left.endsWith(right)',
    ),
    _fn(
      'string_index_of',
      'BinaryInput',
      '',
      'Index of substring: left.indexOf(right)',
    ),
    _fn(
      'string_last_index_of',
      'BinaryInput',
      '',
      'Last index of: left.lastIndexOf(right)',
    ),
    _fn(
      'string_substring',
      'StringSubstringInput',
      '',
      'Substring: value.substring(start, end)',
    ),
    _fn(
      'string_char_at',
      'IndexInput',
      '',
      'Character at index: target[index]',
    ),
    _fn(
      'string_char_code_at',
      'IndexInput',
      '',
      'Char code at index: target.codeUnitAt(index)',
    ),
    // Dart-flavoured alias of string_char_code_at (same engine handler); the
    // encoder routes `String.codeUnitAt(i)` here.
    _fn(
      'string_code_unit_at',
      'IndexInput',
      '',
      'Code unit at index: target.codeUnitAt(index)',
    ),
    _fn(
      'string_from_char_code',
      'UnaryInput',
      '',
      'String from char code: String.fromCharCode(value)',
    ),
    _fn(
      'string_to_upper',
      'UnaryInput',
      '',
      'To upper case: value.toUpperCase()',
    ),
    _fn(
      'string_to_lower',
      'UnaryInput',
      '',
      'To lower case: value.toLowerCase()',
    ),
    _fn('string_trim', 'UnaryInput', '', 'Trim whitespace: value.trim()'),
    _fn('string_trim_start', 'UnaryInput', '', 'Trim start: value.trimLeft()'),
    _fn('string_trim_end', 'UnaryInput', '', 'Trim end: value.trimRight()'),
    _fn(
      'string_replace',
      'StringReplaceInput',
      '',
      'Replace first: value.replaceFirst(from, to)',
    ),
    _fn(
      'string_replace_all',
      'StringReplaceInput',
      '',
      'Replace all: value.replaceAll(from, to)',
    ),
    _fn('string_split', 'BinaryInput', '', 'Split string: left.split(right)'),
    _fn(
      'string_runes',
      'UnaryInput',
      '',
      'Unicode code points: value.runes.toList()',
    ),
    _fn(
      'string_repeat',
      'StringRepeatInput',
      '',
      'Repeat string: value * count',
    ),
    _fn(
      'string_pad_left',
      'StringPadInput',
      '',
      'Pad left: value.padLeft(width, padding)',
    ),
    _fn(
      'string_pad_right',
      'StringPadInput',
      '',
      'Pad right: value.padRight(width, padding)',
    ),

    // --- Regex (universal) ---
    _fn(
      'regex_match',
      'BinaryInput',
      '',
      'Regex match: RegExp(right).hasMatch(left)',
    ),
    _fn(
      'regex_find',
      'BinaryInput',
      '',
      'Regex find first: RegExp(right).firstMatch(left)?.group(0)',
    ),
    _fn(
      'regex_find_all',
      'BinaryInput',
      '',
      'Regex find all: RegExp(right).allMatches(left).map(m => m.group(0))',
    ),
    _fn(
      'regex_replace',
      'StringReplaceInput',
      '',
      'Regex replace first: value.replaceFirst(RegExp(from), to)',
    ),
    _fn(
      'regex_replace_all',
      'StringReplaceInput',
      '',
      'Regex replace all: value.replaceAll(RegExp(from), to)',
    ),

    // --- Math (pure numeric, universal) ---
    _fn('math_abs', 'UnaryInput', '', 'Absolute value: value.abs()'),
    _fn('math_floor', 'UnaryInput', '', 'Floor: value.floor()'),
    _fn('math_ceil', 'UnaryInput', '', 'Ceiling: value.ceil()'),
    _fn('math_round', 'UnaryInput', '', 'Round: value.round()'),
    _fn('math_trunc', 'UnaryInput', '', 'Truncate: value.truncate()'),
    _fn('math_sqrt', 'UnaryInput', '', 'Square root: sqrt(value)'),
    _fn('math_pow', 'BinaryInput', '', 'Power: pow(left, right)'),
    _fn('math_log', 'UnaryInput', '', 'Natural log: log(value)'),
    _fn('math_log2', 'UnaryInput', '', 'Log base 2: log2(value)'),
    _fn('math_log10', 'UnaryInput', '', 'Log base 10: log10(value)'),
    _fn('math_exp', 'UnaryInput', '', 'Exponential: exp(value)'),
    _fn('math_sin', 'UnaryInput', '', 'Sine: sin(value)'),
    _fn('math_cos', 'UnaryInput', '', 'Cosine: cos(value)'),
    _fn('math_tan', 'UnaryInput', '', 'Tangent: tan(value)'),
    _fn('math_asin', 'UnaryInput', '', 'Arc sine: asin(value)'),
    _fn('math_acos', 'UnaryInput', '', 'Arc cosine: acos(value)'),
    _fn('math_atan', 'UnaryInput', '', 'Arc tangent: atan(value)'),
    _fn('math_atan2', 'BinaryInput', '', 'Arc tangent 2: atan2(left, right)'),
    _fn('math_min', 'BinaryInput', '', 'Minimum: min(left, right)'),
    _fn('math_max', 'BinaryInput', '', 'Maximum: max(left, right)'),
    _fn('math_clamp', 'MathClampInput', '', 'Clamp: value.clamp(min, max)'),
    _fn('math_pi', '', '', 'Constant: pi'),
    _fn('math_e', '', '', 'Constant: e'),
    _fn('math_infinity', '', '', 'Constant: infinity'),
    _fn('math_nan', '', '', 'Constant: NaN'),
    _fn('math_is_nan', 'UnaryInput', '', 'Is NaN: value.isNaN'),
    _fn('math_is_finite', 'UnaryInput', '', 'Is finite: value.isFinite'),
    _fn('math_is_infinite', 'UnaryInput', '', 'Is infinite: value.isInfinite'),
    _fn('math_sign', 'UnaryInput', '', 'Sign: value.sign'),
    _fn('math_gcd', 'BinaryInput', '', 'GCD: gcd(left, right)'),
    _fn('math_lcm', 'BinaryInput', '', 'LCM: lcm(left, right)'),
  ]);

  return module;
}