mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
working AStar
This commit is contained in:
parent
9527434be8
commit
13b2c23c01
19 changed files with 578 additions and 81 deletions
|
@ -1,10 +1,11 @@
|
|||
use crate::def::Def;
|
||||
use crate::expr::Expr::*;
|
||||
use crate::expr::{Expr, Recursive};
|
||||
use crate::expr::{Expr, Recursive, WhenBranch};
|
||||
use crate::pattern::Pattern;
|
||||
use roc_collections::all::{MutMap, SendMap};
|
||||
use roc_module::ident::TagName;
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::operator::CalledVia;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_region::all::{Located, Region};
|
||||
use roc_types::subs::{VarStore, Variable};
|
||||
|
@ -60,6 +61,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
|||
STR_ENDS_WITH => str_ends_with,
|
||||
STR_COUNT_GRAPHEMES => str_count_graphemes,
|
||||
STR_FROM_INT => str_from_int,
|
||||
STR_FROM_FLOAT=> str_from_float,
|
||||
LIST_LEN => list_len,
|
||||
LIST_GET => list_get,
|
||||
LIST_SET => list_set,
|
||||
|
@ -144,7 +146,10 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
|||
NUM_MAX_INT => num_max_int,
|
||||
NUM_MIN_INT => num_min_int,
|
||||
NUM_BITWISE_AND => num_bitwise_and,
|
||||
NUM_BITWISE_XOR => num_bitwise_xor
|
||||
NUM_BITWISE_XOR => num_bitwise_xor,
|
||||
RESULT_MAP => result_map,
|
||||
RESULT_MAP_ERR => result_map_err,
|
||||
RESULT_WITH_DEFAULT => result_with_default,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +185,7 @@ pub fn builtin_defs(var_store: &mut VarStore) -> MutMap<Symbol, Def> {
|
|||
Symbol::STR_ENDS_WITH => str_ends_with,
|
||||
Symbol::STR_COUNT_GRAPHEMES => str_count_graphemes,
|
||||
Symbol::STR_FROM_INT => str_from_int,
|
||||
Symbol::STR_FROM_FLOAT=> str_from_float,
|
||||
Symbol::LIST_LEN => list_len,
|
||||
Symbol::LIST_GET => list_get,
|
||||
Symbol::LIST_SET => list_set,
|
||||
|
@ -259,6 +265,9 @@ pub fn builtin_defs(var_store: &mut VarStore) -> MutMap<Symbol, Def> {
|
|||
Symbol::NUM_ASIN => num_asin,
|
||||
Symbol::NUM_MAX_INT => num_max_int,
|
||||
Symbol::NUM_MIN_INT => num_min_int,
|
||||
Symbol::RESULT_MAP => result_map,
|
||||
Symbol::RESULT_MAP_ERR => result_map_err,
|
||||
Symbol::RESULT_WITH_DEFAULT => result_with_default,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1404,7 +1413,7 @@ fn str_count_graphemes(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|||
)
|
||||
}
|
||||
|
||||
/// Str.fromInt : Int -> Str
|
||||
/// Str.fromInt : Int * -> Str
|
||||
fn str_from_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let int_var = var_store.fresh();
|
||||
let str_var = var_store.fresh();
|
||||
|
@ -1424,6 +1433,26 @@ fn str_from_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|||
)
|
||||
}
|
||||
|
||||
/// Str.fromFloat : Float * -> Str
|
||||
fn str_from_float(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let float_var = var_store.fresh();
|
||||
let str_var = var_store.fresh();
|
||||
|
||||
let body = RunLowLevel {
|
||||
op: LowLevel::StrFromFloat,
|
||||
args: vec![(float_var, Var(Symbol::ARG_1))],
|
||||
ret_var: str_var,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(float_var, Symbol::ARG_1)],
|
||||
var_store,
|
||||
body,
|
||||
str_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.concat : List elem, List elem -> List elem
|
||||
fn list_concat(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let list_var = var_store.fresh();
|
||||
|
@ -2365,15 +2394,12 @@ fn set_remove(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|||
|
||||
/// Set.walk : Set k, (k, accum -> accum), accum -> accum
|
||||
fn set_walk(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
use roc_module::operator::CalledVia;
|
||||
|
||||
let dict_var = var_store.fresh();
|
||||
let func_var = var_store.fresh();
|
||||
let key_var = var_store.fresh();
|
||||
let accum_var = var_store.fresh();
|
||||
let wrapper_var = var_store.fresh();
|
||||
|
||||
// let (fn_var, loc_fn, closure_var, ret_var) = &**boxed;
|
||||
let user_function = Box::new((
|
||||
func_var,
|
||||
no_region(Var(Symbol::ARG_2)),
|
||||
|
@ -2835,6 +2861,263 @@ fn list_last(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|||
)
|
||||
}
|
||||
|
||||
fn result_map(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let ret_var = var_store.fresh();
|
||||
let func_var = var_store.fresh();
|
||||
let result_var = var_store.fresh();
|
||||
|
||||
let mut branches = vec![];
|
||||
|
||||
{
|
||||
let user_function = Box::new((
|
||||
func_var,
|
||||
no_region(Var(Symbol::ARG_2)),
|
||||
var_store.fresh(),
|
||||
var_store.fresh(),
|
||||
));
|
||||
|
||||
let call_func = Call(
|
||||
user_function,
|
||||
vec![(var_store.fresh(), no_region(Var(Symbol::ARG_5)))],
|
||||
CalledVia::Space,
|
||||
);
|
||||
|
||||
let tag_name = TagName::Global("Ok".into());
|
||||
|
||||
// ok branch
|
||||
let ok = Tag {
|
||||
variant_var: var_store.fresh(),
|
||||
ext_var: var_store.fresh(),
|
||||
name: tag_name.clone(),
|
||||
arguments: vec![(var_store.fresh(), no_region(call_func))],
|
||||
};
|
||||
|
||||
let pattern = Pattern::AppliedTag {
|
||||
whole_var: result_var,
|
||||
ext_var: var_store.fresh(),
|
||||
tag_name,
|
||||
arguments: vec![(
|
||||
var_store.fresh(),
|
||||
no_region(Pattern::Identifier(Symbol::ARG_5)),
|
||||
)],
|
||||
};
|
||||
|
||||
let branch = WhenBranch {
|
||||
patterns: vec![no_region(pattern)],
|
||||
value: no_region(ok),
|
||||
guard: None,
|
||||
};
|
||||
|
||||
branches.push(branch);
|
||||
}
|
||||
|
||||
{
|
||||
// err branch
|
||||
let tag_name = TagName::Global("Err".into());
|
||||
|
||||
let err = Tag {
|
||||
variant_var: var_store.fresh(),
|
||||
ext_var: var_store.fresh(),
|
||||
name: tag_name.clone(),
|
||||
arguments: vec![(var_store.fresh(), no_region(Var(Symbol::ARG_4)))],
|
||||
};
|
||||
|
||||
let pattern = Pattern::AppliedTag {
|
||||
whole_var: result_var,
|
||||
ext_var: var_store.fresh(),
|
||||
tag_name,
|
||||
arguments: vec![(
|
||||
var_store.fresh(),
|
||||
no_region(Pattern::Identifier(Symbol::ARG_4)),
|
||||
)],
|
||||
};
|
||||
|
||||
let branch = WhenBranch {
|
||||
patterns: vec![no_region(pattern)],
|
||||
value: no_region(err),
|
||||
guard: None,
|
||||
};
|
||||
|
||||
branches.push(branch);
|
||||
}
|
||||
|
||||
let body = When {
|
||||
cond_var: result_var,
|
||||
expr_var: ret_var,
|
||||
region: Region::zero(),
|
||||
loc_cond: Box::new(no_region(Var(Symbol::ARG_1))),
|
||||
branches,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(result_var, Symbol::ARG_1), (func_var, Symbol::ARG_2)],
|
||||
var_store,
|
||||
body,
|
||||
ret_var,
|
||||
)
|
||||
}
|
||||
|
||||
fn result_map_err(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let ret_var = var_store.fresh();
|
||||
let func_var = var_store.fresh();
|
||||
let result_var = var_store.fresh();
|
||||
|
||||
let mut branches = vec![];
|
||||
|
||||
{
|
||||
let user_function = Box::new((
|
||||
func_var,
|
||||
no_region(Var(Symbol::ARG_2)),
|
||||
var_store.fresh(),
|
||||
var_store.fresh(),
|
||||
));
|
||||
|
||||
let call_func = Call(
|
||||
user_function,
|
||||
vec![(var_store.fresh(), no_region(Var(Symbol::ARG_5)))],
|
||||
CalledVia::Space,
|
||||
);
|
||||
|
||||
let tag_name = TagName::Global("Err".into());
|
||||
|
||||
// ok branch
|
||||
let ok = Tag {
|
||||
variant_var: var_store.fresh(),
|
||||
ext_var: var_store.fresh(),
|
||||
name: tag_name.clone(),
|
||||
arguments: vec![(var_store.fresh(), no_region(call_func))],
|
||||
};
|
||||
|
||||
let pattern = Pattern::AppliedTag {
|
||||
whole_var: result_var,
|
||||
ext_var: var_store.fresh(),
|
||||
tag_name,
|
||||
arguments: vec![(
|
||||
var_store.fresh(),
|
||||
no_region(Pattern::Identifier(Symbol::ARG_5)),
|
||||
)],
|
||||
};
|
||||
|
||||
let branch = WhenBranch {
|
||||
patterns: vec![no_region(pattern)],
|
||||
value: no_region(ok),
|
||||
guard: None,
|
||||
};
|
||||
|
||||
branches.push(branch);
|
||||
}
|
||||
|
||||
{
|
||||
// err branch
|
||||
let tag_name = TagName::Global("Ok".into());
|
||||
|
||||
let err = Tag {
|
||||
variant_var: var_store.fresh(),
|
||||
ext_var: var_store.fresh(),
|
||||
name: tag_name.clone(),
|
||||
arguments: vec![(var_store.fresh(), no_region(Var(Symbol::ARG_4)))],
|
||||
};
|
||||
|
||||
let pattern = Pattern::AppliedTag {
|
||||
whole_var: result_var,
|
||||
ext_var: var_store.fresh(),
|
||||
tag_name,
|
||||
arguments: vec![(
|
||||
var_store.fresh(),
|
||||
no_region(Pattern::Identifier(Symbol::ARG_4)),
|
||||
)],
|
||||
};
|
||||
|
||||
let branch = WhenBranch {
|
||||
patterns: vec![no_region(pattern)],
|
||||
value: no_region(err),
|
||||
guard: None,
|
||||
};
|
||||
|
||||
branches.push(branch);
|
||||
}
|
||||
|
||||
let body = When {
|
||||
cond_var: result_var,
|
||||
expr_var: ret_var,
|
||||
region: Region::zero(),
|
||||
loc_cond: Box::new(no_region(Var(Symbol::ARG_1))),
|
||||
branches,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(result_var, Symbol::ARG_1), (func_var, Symbol::ARG_2)],
|
||||
var_store,
|
||||
body,
|
||||
ret_var,
|
||||
)
|
||||
}
|
||||
|
||||
fn result_with_default(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let ret_var = var_store.fresh();
|
||||
let result_var = var_store.fresh();
|
||||
|
||||
let mut branches = vec![];
|
||||
|
||||
{
|
||||
// ok branch
|
||||
let tag_name = TagName::Global("Ok".into());
|
||||
|
||||
let pattern = Pattern::AppliedTag {
|
||||
whole_var: result_var,
|
||||
ext_var: var_store.fresh(),
|
||||
tag_name,
|
||||
arguments: vec![(ret_var, no_region(Pattern::Identifier(Symbol::ARG_3)))],
|
||||
};
|
||||
|
||||
let branch = WhenBranch {
|
||||
patterns: vec![no_region(pattern)],
|
||||
value: no_region(Var(Symbol::ARG_3)),
|
||||
guard: None,
|
||||
};
|
||||
|
||||
branches.push(branch);
|
||||
}
|
||||
|
||||
{
|
||||
// err branch
|
||||
let tag_name = TagName::Global("Err".into());
|
||||
|
||||
let pattern = Pattern::AppliedTag {
|
||||
whole_var: result_var,
|
||||
ext_var: var_store.fresh(),
|
||||
tag_name,
|
||||
arguments: vec![(var_store.fresh(), no_region(Pattern::Underscore))],
|
||||
};
|
||||
|
||||
let branch = WhenBranch {
|
||||
patterns: vec![no_region(pattern)],
|
||||
value: no_region(Var(Symbol::ARG_2)),
|
||||
guard: None,
|
||||
};
|
||||
|
||||
branches.push(branch);
|
||||
}
|
||||
|
||||
let body = When {
|
||||
cond_var: result_var,
|
||||
expr_var: ret_var,
|
||||
region: Region::zero(),
|
||||
loc_cond: Box::new(no_region(Var(Symbol::ARG_1))),
|
||||
branches,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(result_var, Symbol::ARG_1), (ret_var, Symbol::ARG_2)],
|
||||
var_store,
|
||||
body,
|
||||
ret_var,
|
||||
)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn no_region<T>(value: T) -> Located<T> {
|
||||
Located {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue