mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Merge remote-tracking branch 'remote/main' into rebuild-platform
This commit is contained in:
commit
de9491eb7f
24 changed files with 361 additions and 140 deletions
|
@ -28,7 +28,7 @@ pub const MOD_APP: ModName = ModName(b"UserApp");
|
|||
pub const STATIC_STR_NAME: ConstName = ConstName(&Symbol::STR_ALIAS_ANALYSIS_STATIC.to_ne_bytes());
|
||||
pub const STATIC_LIST_NAME: ConstName = ConstName(b"THIS IS A STATIC LIST");
|
||||
|
||||
const ENTRY_POINT_NAME: &[u8] = b"mainForHost";
|
||||
const DEFAULT_ENTRY_POINT_NAME: &[u8] = b"mainForHost";
|
||||
|
||||
pub fn func_name_bytes(proc: &Proc) -> [u8; SIZE] {
|
||||
let bytes = func_name_bytes_help(
|
||||
|
@ -149,6 +149,7 @@ where
|
|||
I1: Iterator<Item = &'r Proc<'a>>,
|
||||
I2: Iterator<Item = &'r HostExposedLambdaSet<'a>>,
|
||||
{
|
||||
let mut entry_point_names = bumpalo::vec![in arena;];
|
||||
let main_module = {
|
||||
let mut m = ModDefBuilder::new();
|
||||
|
||||
|
@ -237,34 +238,38 @@ where
|
|||
}
|
||||
|
||||
match entry_point {
|
||||
EntryPoint::Single(SingleEntryPoint {
|
||||
symbol: entry_point_symbol,
|
||||
layout: entry_point_layout,
|
||||
}) => {
|
||||
// the entry point wrapper
|
||||
let roc_main_bytes = func_name_bytes_help(
|
||||
entry_point_symbol,
|
||||
entry_point_layout.arguments.iter().copied(),
|
||||
Niche::NONE,
|
||||
entry_point_layout.result,
|
||||
);
|
||||
let roc_main = FuncName(&roc_main_bytes);
|
||||
EntryPoint::Program(entry_points) => {
|
||||
for SingleEntryPoint {
|
||||
name: entry_point_name,
|
||||
symbol: entry_point_symbol,
|
||||
layout: entry_point_layout,
|
||||
} in entry_points
|
||||
{
|
||||
let roc_main_bytes = func_name_bytes_help(
|
||||
*entry_point_symbol,
|
||||
entry_point_layout.arguments.iter().copied(),
|
||||
Niche::NONE,
|
||||
entry_point_layout.result,
|
||||
);
|
||||
let roc_main = FuncName(&roc_main_bytes);
|
||||
|
||||
let mut env = Env::new();
|
||||
let mut env = Env::new();
|
||||
|
||||
let entry_point_function = build_entry_point(
|
||||
&mut env,
|
||||
interner,
|
||||
entry_point_layout,
|
||||
Some(roc_main),
|
||||
&host_exposed_functions,
|
||||
&erased_functions,
|
||||
)?;
|
||||
let entry_point_function = build_entry_point(
|
||||
&mut env,
|
||||
interner,
|
||||
*entry_point_layout,
|
||||
Some(roc_main),
|
||||
&host_exposed_functions,
|
||||
&erased_functions,
|
||||
)?;
|
||||
|
||||
type_definitions.extend(env.type_names);
|
||||
type_definitions.extend(env.type_names);
|
||||
|
||||
let entry_point_name = FuncName(ENTRY_POINT_NAME);
|
||||
m.add_func(entry_point_name, entry_point_function)?;
|
||||
entry_point_names.push(entry_point_name.as_bytes());
|
||||
let entry_point_name = FuncName(entry_point_name.as_bytes());
|
||||
m.add_func(entry_point_name, entry_point_function)?;
|
||||
}
|
||||
}
|
||||
EntryPoint::Expects { symbols } => {
|
||||
// construct a big pattern match picking one of the expects at random
|
||||
|
@ -296,7 +301,8 @@ where
|
|||
|
||||
type_definitions.extend(env.type_names);
|
||||
|
||||
let entry_point_name = FuncName(ENTRY_POINT_NAME);
|
||||
entry_point_names.push(DEFAULT_ENTRY_POINT_NAME);
|
||||
let entry_point_name = FuncName(DEFAULT_ENTRY_POINT_NAME);
|
||||
m.add_func(entry_point_name, entry_point_function)?;
|
||||
}
|
||||
}
|
||||
|
@ -335,11 +341,13 @@ where
|
|||
let mut p = ProgramBuilder::new();
|
||||
p.add_mod(MOD_APP, main_module)?;
|
||||
|
||||
p.add_entry_point(
|
||||
EntryPointName(ENTRY_POINT_NAME),
|
||||
MOD_APP,
|
||||
FuncName(ENTRY_POINT_NAME),
|
||||
)?;
|
||||
for entry_point_name in entry_point_names {
|
||||
p.add_entry_point(
|
||||
EntryPointName(entry_point_name),
|
||||
MOD_APP,
|
||||
FuncName(entry_point_name),
|
||||
)?;
|
||||
}
|
||||
|
||||
p.build()?
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::link::{link, preprocess_host_wasm32, rebuild_host, LinkType, LinkingStrategy};
|
||||
use bumpalo::collections::CollectIn;
|
||||
use bumpalo::Bump;
|
||||
use inkwell::memory_buffer::MemoryBuffer;
|
||||
use roc_error_macros::internal_error;
|
||||
|
@ -226,11 +227,16 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
exposed_to_host,
|
||||
platform_path: _,
|
||||
} => {
|
||||
// TODO support multiple of these!
|
||||
debug_assert_eq!(exposed_to_host.len(), 1);
|
||||
let (symbol, layout) = exposed_to_host[0];
|
||||
let entry_points: bumpalo::collections::Vec<_> = exposed_to_host
|
||||
.iter()
|
||||
.map(|(fn_name, symbol, layout)| SingleEntryPoint {
|
||||
name: fn_name,
|
||||
symbol: *symbol,
|
||||
layout: *layout,
|
||||
})
|
||||
.collect_in(arena);
|
||||
|
||||
roc_mono::ir::EntryPoint::Single(SingleEntryPoint { symbol, layout })
|
||||
roc_mono::ir::EntryPoint::Program(entry_points.into_bump_slice())
|
||||
}
|
||||
EntryPoint::Test => roc_mono::ir::EntryPoint::Expects { symbols: &[] },
|
||||
};
|
||||
|
|
|
@ -120,7 +120,7 @@ impl<'a> Formattable for ProvidesTo<'a> {
|
|||
|
||||
impl<'a> Formattable for PlatformRequires<'a> {
|
||||
fn is_multiline(&self) -> bool {
|
||||
is_collection_multiline(&self.rigids) || self.signature.is_multiline()
|
||||
is_collection_multiline(&self.rigids) || is_collection_multiline(&self.signatures)
|
||||
}
|
||||
|
||||
fn format_with_options(
|
||||
|
@ -260,10 +260,14 @@ pub fn fmt_platform_header<'a>(buf: &mut Buf, header: &'a PlatformHeader<'a>) {
|
|||
fn fmt_requires(buf: &mut Buf, requires: &PlatformRequires, indent: u16) {
|
||||
fmt_collection(buf, indent, Braces::Curly, requires.rigids, Newlines::No);
|
||||
|
||||
buf.push_str(" {");
|
||||
buf.spaces(1);
|
||||
requires.signature.value.format(buf, indent);
|
||||
buf.push_str(" }");
|
||||
fmt_collection(
|
||||
buf,
|
||||
indent,
|
||||
Braces::Curly,
|
||||
requires.signatures,
|
||||
Newlines::No,
|
||||
);
|
||||
}
|
||||
|
||||
impl<'a> Formattable for TypedIdent<'a> {
|
||||
|
|
|
@ -5592,7 +5592,7 @@ pub fn build_wasm_test_wrapper<'a, 'ctx>(
|
|||
opt_level,
|
||||
procedures,
|
||||
vec![],
|
||||
EntryPoint::Single(entry_point),
|
||||
EntryPoint::Program(env.arena.alloc([entry_point])),
|
||||
Some(&std::env::temp_dir().join("test.ll")),
|
||||
);
|
||||
|
||||
|
@ -5619,7 +5619,7 @@ pub fn build_procedures_return_main<'a, 'ctx>(
|
|||
opt_level,
|
||||
procedures,
|
||||
host_exposed_lambda_sets,
|
||||
EntryPoint::Single(entry_point),
|
||||
EntryPoint::Program(env.arena.alloc([entry_point])),
|
||||
Some(&std::env::temp_dir().join("test.ll")),
|
||||
);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ use roc_parse::ast::{self, CommentOrNewline, ExtractSpaces, Spaced, ValueDef};
|
|||
use roc_parse::header::parse_module_defs;
|
||||
use roc_parse::header::{
|
||||
self, AppHeader, ExposedName, HeaderType, ImportsKeywordItem, PackageEntry, PackageHeader,
|
||||
PlatformHeader, To, TypedIdent,
|
||||
PlatformHeader, To,
|
||||
};
|
||||
use roc_parse::parser::{FileError, SourceError, SyntaxError};
|
||||
use roc_problem::Severity;
|
||||
|
@ -667,7 +667,7 @@ enum PlatformPath<'a> {
|
|||
#[derive(Debug)]
|
||||
struct PlatformData<'a> {
|
||||
module_id: ModuleId,
|
||||
provides: &'a [(Loc<ExposedName<'a>>, Loc<TypedIdent<'a>>)],
|
||||
provides: &'a [Loc<ExposedName<'a>>],
|
||||
is_prebuilt: bool,
|
||||
}
|
||||
|
||||
|
@ -3171,7 +3171,7 @@ fn finish_specialization<'a>(
|
|||
let proc_layout =
|
||||
proc_layout_for(state.procedures.keys().copied(), symbol);
|
||||
|
||||
buf.push((symbol, proc_layout));
|
||||
buf.push(("", symbol, proc_layout));
|
||||
}
|
||||
|
||||
buf.into_bump_slice()
|
||||
|
@ -3185,13 +3185,14 @@ fn finish_specialization<'a>(
|
|||
let mut buf =
|
||||
bumpalo::collections::Vec::with_capacity_in(provides.len(), arena);
|
||||
|
||||
for (loc_name, _loc_typed_ident) in provides {
|
||||
let ident_id = ident_ids.get_or_insert(loc_name.value.as_str());
|
||||
for loc_name in provides {
|
||||
let fn_name = loc_name.value.as_str();
|
||||
let ident_id = ident_ids.get_or_insert(fn_name);
|
||||
let symbol = Symbol::new(module_id, ident_id);
|
||||
let proc_layout =
|
||||
proc_layout_for(state.procedures.keys().copied(), symbol);
|
||||
|
||||
buf.push((symbol, proc_layout));
|
||||
buf.push((fn_name, symbol, proc_layout));
|
||||
}
|
||||
|
||||
buf.into_bump_slice()
|
||||
|
@ -4987,15 +4988,16 @@ fn build_platform_header<'a>(
|
|||
comments: &'a [CommentOrNewline<'a>],
|
||||
module_timing: ModuleTiming,
|
||||
) -> Result<(ModuleId, PQModuleName<'a>, ModuleHeader<'a>), LoadingProblem<'a>> {
|
||||
let requires = arena.alloc([Loc::at(
|
||||
header.requires.item.signature.region,
|
||||
header.requires.item.signature.extract_spaces().item,
|
||||
)]);
|
||||
let requires = header
|
||||
.requires
|
||||
.item
|
||||
.signatures
|
||||
.map_items(arena, |item| {
|
||||
Loc::at(item.region, item.extract_spaces().item)
|
||||
})
|
||||
.items;
|
||||
let provides = bumpalo::collections::Vec::from_iter_in(
|
||||
unspace(arena, header.provides.item.items)
|
||||
.iter()
|
||||
.copied()
|
||||
.zip(requires.iter().copied()),
|
||||
unspace(arena, header.provides.item.items).iter().copied(),
|
||||
arena,
|
||||
);
|
||||
let packages = unspace(arena, header.packages.item.items);
|
||||
|
@ -5447,7 +5449,7 @@ fn parse<'a>(
|
|||
if let HeaderType::Platform { provides, .. } = header.header_type {
|
||||
exposed.reserve(provides.len());
|
||||
|
||||
for (loc_name, _loc_typed_ident) in provides.iter() {
|
||||
for loc_name in provides.iter() {
|
||||
// Use get_or_insert here because the ident_ids may already
|
||||
// created an IdentId for this, when it was imported exposed
|
||||
// in a dependent module.
|
||||
|
|
|
@ -213,7 +213,7 @@ pub struct ParsedModule<'a> {
|
|||
#[derive(Debug)]
|
||||
pub enum EntryPoint<'a> {
|
||||
Executable {
|
||||
exposed_to_host: &'a [(Symbol, ProcLayout<'a>)],
|
||||
exposed_to_host: &'a [(&'a str, Symbol, ProcLayout<'a>)],
|
||||
platform_path: PathBuf,
|
||||
},
|
||||
Test,
|
||||
|
|
|
@ -132,13 +132,14 @@ pub enum OptLevel {
|
|||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct SingleEntryPoint<'a> {
|
||||
pub name: &'a str,
|
||||
pub symbol: Symbol,
|
||||
pub layout: ProcLayout<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum EntryPoint<'a> {
|
||||
Single(SingleEntryPoint<'a>),
|
||||
Program(&'a [SingleEntryPoint<'a>]),
|
||||
Expects { symbols: &'a [Symbol] },
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::ast::{
|
|||
Collection, CommentOrNewline, Defs, Header, Malformed, Pattern, Spaced, Spaces, SpacesBefore,
|
||||
StrLiteral, TypeAnnotation,
|
||||
};
|
||||
use crate::blankspace::{space0_around_ee, space0_before_e, space0_e};
|
||||
use crate::blankspace::{space0_before_e, space0_e};
|
||||
use crate::expr::merge_spaces;
|
||||
use crate::ident::{self, lowercase_ident, unqualified_ident, UppercaseIdent};
|
||||
use crate::parser::Progress::{self, *};
|
||||
|
@ -587,7 +587,7 @@ fn requires<'a>(
|
|||
fn platform_requires<'a>() -> impl Parser<'a, PlatformRequires<'a>, ERequires<'a>> {
|
||||
record!(PlatformRequires {
|
||||
rigids: skip_second(requires_rigids(), space0_e(ERequires::ListStart)),
|
||||
signature: requires_typed_ident()
|
||||
signatures: requires_typed_ident()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -607,18 +607,15 @@ fn requires_rigids<'a>(
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn requires_typed_ident<'a>() -> impl Parser<'a, Loc<Spaced<'a, TypedIdent<'a>>>, ERequires<'a>> {
|
||||
skip_first(
|
||||
fn requires_typed_ident<'a>(
|
||||
) -> impl Parser<'a, Collection<'a, Loc<Spaced<'a, TypedIdent<'a>>>>, ERequires<'a>> {
|
||||
reset_min_indent(collection_trailing_sep_e(
|
||||
byte(b'{', ERequires::ListStart),
|
||||
skip_second(
|
||||
reset_min_indent(space0_around_ee(
|
||||
specialize_err(ERequires::TypedIdent, loc(typed_ident())),
|
||||
ERequires::ListStart,
|
||||
ERequires::ListEnd,
|
||||
)),
|
||||
byte(b'}', ERequires::ListStart),
|
||||
),
|
||||
)
|
||||
specialize_err(ERequires::TypedIdent, loc(typed_ident())),
|
||||
byte(b',', ERequires::ListEnd),
|
||||
byte(b'}', ERequires::ListEnd),
|
||||
Spaced::SpaceBefore,
|
||||
))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -955,7 +952,7 @@ pub enum HeaderType<'a> {
|
|||
opt_app_module_id: Option<ModuleId>,
|
||||
/// the name and type scheme of the main function (required by the platform)
|
||||
/// (type scheme is currently unused)
|
||||
provides: &'a [(Loc<ExposedName<'a>>, Loc<TypedIdent<'a>>)],
|
||||
provides: &'a [Loc<ExposedName<'a>>],
|
||||
requires: &'a [Loc<TypedIdent<'a>>],
|
||||
requires_types: &'a [Loc<UppercaseIdent<'a>>],
|
||||
exposes: &'a [Loc<ModuleName<'a>>],
|
||||
|
@ -1239,7 +1236,7 @@ pub struct PackageHeader<'a> {
|
|||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct PlatformRequires<'a> {
|
||||
pub rigids: Collection<'a, Loc<Spaced<'a, UppercaseIdent<'a>>>>,
|
||||
pub signature: Loc<Spaced<'a, TypedIdent<'a>>>,
|
||||
pub signatures: Collection<'a, Loc<Spaced<'a, TypedIdent<'a>>>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
|
@ -1393,7 +1390,7 @@ impl<'a> Malformed for PackageHeader<'a> {
|
|||
|
||||
impl<'a> Malformed for PlatformRequires<'a> {
|
||||
fn is_malformed(&self) -> bool {
|
||||
self.signature.is_malformed()
|
||||
self.signatures.items.iter().any(|x| x.is_malformed())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ impl<'a> Normalize<'a> for PlatformRequires<'a> {
|
|||
fn normalize(&self, arena: &'a Bump) -> Self {
|
||||
PlatformRequires {
|
||||
rigids: self.rigids.normalize(arena),
|
||||
signature: self.signature.normalize(arena),
|
||||
signatures: self.signatures.map_items(arena, |x| x.normalize(arena)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,9 +113,13 @@ pub fn helper(
|
|||
} => {
|
||||
// TODO support multiple of these!
|
||||
debug_assert_eq!(exposed_to_host.len(), 1);
|
||||
let (symbol, layout) = exposed_to_host[0];
|
||||
let (name, symbol, layout) = exposed_to_host[0];
|
||||
|
||||
SingleEntryPoint { symbol, layout }
|
||||
SingleEntryPoint {
|
||||
name,
|
||||
symbol,
|
||||
layout,
|
||||
}
|
||||
}
|
||||
EntryPoint::Test => {
|
||||
unreachable!()
|
||||
|
|
|
@ -243,9 +243,13 @@ fn create_llvm_module<'a>(
|
|||
} => {
|
||||
// TODO support multiple of these!
|
||||
debug_assert_eq!(exposed_to_host.len(), 1);
|
||||
let (symbol, layout) = exposed_to_host[0];
|
||||
let (name, symbol, layout) = exposed_to_host[0];
|
||||
|
||||
SingleEntryPoint { symbol, layout }
|
||||
SingleEntryPoint {
|
||||
name,
|
||||
symbol,
|
||||
layout,
|
||||
}
|
||||
}
|
||||
EntryPoint::Test => {
|
||||
unreachable!()
|
||||
|
|
|
@ -14,14 +14,24 @@ SpacesBefore {
|
|||
},
|
||||
item: PlatformRequires {
|
||||
rigids: [],
|
||||
signature: @40-49 TypedIdent {
|
||||
ident: @40-44 "main",
|
||||
spaces_before_colon: [],
|
||||
ann: @47-49 Record {
|
||||
fields: [],
|
||||
ext: None,
|
||||
signatures: [
|
||||
@40-49 TypedIdent {
|
||||
ident: @40-44 "init",
|
||||
spaces_before_colon: [],
|
||||
ann: @47-49 Record {
|
||||
fields: [],
|
||||
ext: None,
|
||||
},
|
||||
},
|
||||
},
|
||||
@51-62 TypedIdent {
|
||||
ident: @51-57 "update",
|
||||
spaces_before_colon: [],
|
||||
ann: @60-62 Record {
|
||||
fields: [],
|
||||
ext: None,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
exposes: KeywordItem {
|
||||
|
|
|
@ -1 +1 @@
|
|||
platform "rtfeldman/blah" requires {} { main : {} } exposes [] packages {} imports [] provides []
|
||||
platform "rtfeldman/blah" requires {} { init : {}, update : {} } exposes [] packages {} imports [] provides []
|
||||
|
|
|
@ -16,24 +16,26 @@ SpacesBefore {
|
|||
},
|
||||
item: PlatformRequires {
|
||||
rigids: [],
|
||||
signature: @32-49 TypedIdent {
|
||||
ident: @32-36 "main",
|
||||
spaces_before_colon: [],
|
||||
ann: @39-49 Apply(
|
||||
"",
|
||||
"Task",
|
||||
[
|
||||
@44-46 Record {
|
||||
fields: [],
|
||||
ext: None,
|
||||
},
|
||||
@47-49 TagUnion {
|
||||
ext: None,
|
||||
tags: [],
|
||||
},
|
||||
],
|
||||
),
|
||||
},
|
||||
signatures: [
|
||||
@32-49 TypedIdent {
|
||||
ident: @32-36 "main",
|
||||
spaces_before_colon: [],
|
||||
ann: @39-49 Apply(
|
||||
"",
|
||||
"Task",
|
||||
[
|
||||
@44-46 Record {
|
||||
fields: [],
|
||||
ext: None,
|
||||
},
|
||||
@47-49 TagUnion {
|
||||
ext: None,
|
||||
tags: [],
|
||||
},
|
||||
],
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
exposes: KeywordItem {
|
||||
|
|
|
@ -20,14 +20,16 @@ SpacesBefore {
|
|||
"Model",
|
||||
),
|
||||
],
|
||||
signature: @45-54 TypedIdent {
|
||||
ident: @45-49 "main",
|
||||
spaces_before_colon: [],
|
||||
ann: @52-54 Record {
|
||||
fields: [],
|
||||
ext: None,
|
||||
signatures: [
|
||||
@45-54 TypedIdent {
|
||||
ident: @45-49 "main",
|
||||
spaces_before_colon: [],
|
||||
ann: @52-54 Record {
|
||||
fields: [],
|
||||
ext: None,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
exposes: KeywordItem {
|
||||
|
|
|
@ -23,26 +23,28 @@ SpacesBefore {
|
|||
"Model",
|
||||
),
|
||||
],
|
||||
signature: @55-77 TypedIdent {
|
||||
ident: @55-59 "main",
|
||||
spaces_before_colon: [],
|
||||
ann: @62-77 Apply(
|
||||
"",
|
||||
"App",
|
||||
[
|
||||
@66-71 Apply(
|
||||
"",
|
||||
"Flags",
|
||||
[],
|
||||
),
|
||||
@72-77 Apply(
|
||||
"",
|
||||
"Model",
|
||||
[],
|
||||
),
|
||||
],
|
||||
),
|
||||
},
|
||||
signatures: [
|
||||
@55-77 TypedIdent {
|
||||
ident: @55-59 "main",
|
||||
spaces_before_colon: [],
|
||||
ann: @62-77 Apply(
|
||||
"",
|
||||
"App",
|
||||
[
|
||||
@66-71 Apply(
|
||||
"",
|
||||
"Flags",
|
||||
[],
|
||||
),
|
||||
@72-77 Apply(
|
||||
"",
|
||||
"Model",
|
||||
[],
|
||||
),
|
||||
],
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
exposes: KeywordItem {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue