diff --git a/compiler/mono/src/alias_analysis.rs b/compiler/mono/src/alias_analysis.rs index 7d3c509d70..ee78ea5860 100644 --- a/compiler/mono/src/alias_analysis.rs +++ b/compiler/mono/src/alias_analysis.rs @@ -739,15 +739,20 @@ fn lowlevel_spec( builder.add_sub_block(block, sub_block) } + NumToFloat => { + // just dream up a unit value + builder.add_make_tuple(block, &[]) + } Eq | NotEq => { // just dream up a unit value builder.add_make_tuple(block, &[]) } - NumLte | NumLt | NumGt | NumGte => { + NumLte | NumLt | NumGt | NumGte | NumCompare => { // just dream up a unit value builder.add_make_tuple(block, &[]) } - ListLen => { + ListLen | DictSize => { + // TODO should this touch the heap cell? // just dream up a unit value builder.add_make_tuple(block, &[]) } @@ -775,7 +780,70 @@ fn lowlevel_spec( Ok(list) } + ListAppend => { + let list = env.symbols[&arguments[0]]; + let to_insert = env.symbols[&arguments[1]]; + + let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?; + let cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?; + + let _unit = builder.add_update(block, update_mode_var, cell)?; + + builder.add_bag_insert(block, bag, to_insert)?; + + Ok(list) + } + DictEmpty => { + match layout { + Layout::Builtin(Builtin::EmptyDict) => { + // just make up an element type + let type_id = builder.add_tuple_type(&[])?; + new_dict(builder, block, type_id, type_id) + } + Layout::Builtin(Builtin::Dict(key_layout, value_layout)) => { + let key_id = layout_spec(builder, key_layout)?; + let value_id = layout_spec(builder, value_layout)?; + new_dict(builder, block, key_id, value_id) + } + _ => unreachable!("empty array does not have a list layout"), + } + } + DictGetUnsafe => { + // NOTE DictGetUnsafe returns a { flag: Bool, value: v } + // when the flag is True, the value is found and defined; + // otherwise it is not and `Dict.get` should return `Err ...` + + let dict = env.symbols[&arguments[0]]; + let key = env.symbols[&arguments[1]]; + + // indicate that we use the key + builder.add_recursive_touch(block, key)?; + + let bag = builder.add_get_tuple_field(block, dict, DICT_BAG_INDEX)?; + let cell = builder.add_get_tuple_field(block, dict, DICT_CELL_INDEX)?; + + let _unit = builder.add_touch(block, cell)?; + + builder.add_bag_get(block, bag) + } + DictInsert => { + let dict = env.symbols[&arguments[0]]; + let key = env.symbols[&arguments[1]]; + let value = env.symbols[&arguments[2]]; + + let key_value = builder.add_make_tuple(block, &[key, value])?; + + let bag = builder.add_get_tuple_field(block, dict, DICT_BAG_INDEX)?; + let cell = builder.add_get_tuple_field(block, dict, DICT_CELL_INDEX)?; + + let _unit = builder.add_update(block, update_mode_var, cell)?; + + builder.add_bag_insert(block, bag, key_value)?; + + Ok(dict) + } _other => { + // println!("missing {:?}", _other); // TODO overly pessimstic let arguments: Vec<_> = arguments.iter().map(|symbol| env.symbols[symbol]).collect(); @@ -1051,6 +1119,18 @@ fn new_list(builder: &mut FuncDefBuilder, block: BlockId, element_type: TypeId) builder.add_make_tuple(block, &[cell, bag]) } +fn new_dict( + builder: &mut FuncDefBuilder, + block: BlockId, + key_type: TypeId, + value_type: TypeId, +) -> Result { + let cell = builder.add_new_heap_cell(block)?; + let element_type = builder.add_tuple_type(&[key_type, value_type])?; + let bag = builder.add_empty_bag(block, element_type)?; + builder.add_make_tuple(block, &[cell, bag]) +} + fn new_static_string(builder: &mut FuncDefBuilder, block: BlockId) -> Result { let module = MOD_APP; diff --git a/www/public/styles.css b/www/public/styles.css index 27f88aacd1..b90cfb58a2 100644 --- a/www/public/styles.css +++ b/www/public/styles.css @@ -282,8 +282,9 @@ code { font-family: var(--font-mono); color: var(--code-color); background-color: var(--code-bg-color); - padding: 2px 8px; + padding: 0 8px; display: inline-block; + line-height: 28px; } code a {