Skip to content

Compiler crashed #1179

@gyreas

Description

@gyreas
   Operating System: linux
   Architecture:     x86_64
   Version:          v1.1.17+c3a7fba
   
   crates/aiken-lang/src/test_framework.rs:1188:30
   
       failed to reify assertion operand?: "invalid type annotation Tuple { elems: [App { public: true, contains_opaque: false, module: \"\", name: \"Int\", args: [], alias: None }, App { public: true, contains_opaque: false, module: \"\", name: \"Int\", args: [], alias: None }], alias: None } for 1st constructor with fields: Indef([Constr(Constr { tag: 121, any_constructor: None, fields: Def([]) })])"

running: aiken c --watch --trace-level=verbose -m printf/fmt,

on this:

use aiken/collection/list
use aiken/primitive/bytearray.{Byte}

// use aiken/primitive/string

type ModifierKind {
  String
  Number
  Ignored
}

type Modifier {
  kind: ModifierKind,
}

type Formatted {
  // only valid for byteslices
  range: Option<(Int, Int)>,
  // it is consumed on depend after matching with the corresponding parameter
  modifier: Option<Modifier>,
}

type Context {
  // wher the first non format byteslice is found
  start: Int,
  acc: List<Formatted>,
}

fn parse_format(fmt: ByteArray) -> List<Formatted> {
  let ctx = parse_fmt(fmt, Context { start: -1, acc: [] })
  ctx.acc
  // list.reverse(parse_fmt(fmt, Context { start: -1, acc: [] }))
}

fn parse_fmt(fmt: ByteArray, ctx: Context) -> Context {
  when peek_byte(fmt) is {
    None -> ctx
    Some(b) ->
      if b == chr("%") {
        // TODO: put it back as single '%' (not handle yet, until slicing)
        //  handle the case where double '%' is used to 
        let mod = parse_format_aux(fmt)
        let acc = [Formatted { range: None, modifier: Some(mod) }, ..ctx.acc]
        parse_fmt(bytearray.drop(fmt, 2), Context { start: ctx.start, acc })
      } else {
        parse_fmt(bytearray.drop(fmt, 1), ctx)
      }
  }
}

// this is only called if a '%' is seen
// `fmt` still contains the '%', however
fn parse_format_aux(fmt: ByteArray) -> Modifier {
  when peek_byte(fmt) is {
    None -> fail
    Some(b) -> {
      expect b == chr("%")
      let fmt = bytearray.drop(fmt, 1)
      let b = peek_byte(fmt)
      expect Some(b) = b

      let kind: ModifierKind =
        if b == chr("s") {
          String
        } else if b == chr("d") {
          Number
        } else if b == chr("%") {
          Ignored
        } else {
          fail
        }

      Modifier { kind }
    }
  }
}

fn peek_byte(ba: ByteArray) -> Option<Byte> {
  if bytearray.is_empty(ba) {
    None
  } else {
    Some(bytearray.at(ba, 0))
  }
}

fn chr(byte: ByteArray) -> Byte {
  expect bytearray.length(byte) == 1
  bytearray.at(byte, 0)
}

test parse_kind() {
  let expected =
    Context {
      start: 1,
      acc: [
        Formatted { range: None, modifier: Some(Modifier { kind: String }) },
      ],
    }
  parse_fmt("%s", Context { start: -1, acc: [] }) == expected
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    🪣 Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions