mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Merge branch 'update_zig' of https://github.com/rtfeldman/roc into dec-to-string
This commit is contained in:
commit
ac4d718039
41 changed files with 1011 additions and 359 deletions
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
|
@ -22,4 +22,3 @@ jobs:
|
|||
|
||||
- name: install dependencies, build, run zig tests, rustfmt, clippy, cargo test --release
|
||||
run: ./ci/safe-earthly.sh +test-all
|
||||
|
||||
|
|
22
.github/workflows/www.yml
vendored
Normal file
22
.github/workflows/www.yml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
name: deploy www.roc-lang.org
|
||||
|
||||
# Whenever a commit lands on trunk, deploy the site
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- deploy-www # TODO change to trunk
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: 'Deploy to Netlify'
|
||||
runs-on: [self-hosted]
|
||||
steps:
|
||||
- uses: jsmrcaga/action-netlify-deploy@v1.6.0
|
||||
with:
|
||||
install_command: 'pwd; cd ../../www'
|
||||
build_command: 'bash build.sh'
|
||||
build_directory: 'build'
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
||||
NETLIFY_DEPLOY_MESSAGE: "Deploy git ref ${{ github.ref }}"
|
||||
NETLIFY_DEPLOY_TO_PROD: true
|
|
@ -40,11 +40,16 @@ sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev
|
|||
```
|
||||
|
||||
### Zig
|
||||
**version: 0.7.x**
|
||||
**version: 0.8.0**
|
||||
|
||||
If you're on MacOS, you can install with `brew install zig`
|
||||
If you're on Ubuntu and use Snap, you can install with `snap install zig --classic --beta`
|
||||
For any other OS, checkout the [Zig installation page](https://github.com/ziglang/zig/wiki/Install-Zig-from-a-Package-Manager)
|
||||
For any OS, you can use [`zigup`](https://github.com/marler8997/zigup) to manage zig installations.
|
||||
|
||||
If you prefer a package manager, you can try the following:
|
||||
- For MacOS, you can install with `brew install zig`
|
||||
- For, Ubuntu, you can use Snap, you can install with `snap install zig --classic --beta`
|
||||
- For other systems, checkout this [page](https://github.com/ziglang/zig/wiki/Install-Zig-from-a-Package-Manager)
|
||||
|
||||
If you want to install it manually, you can also download Zig directly [here](https://ziglang.org/download/). Just make sure you download the right version, the bleeding edge master build is the first download link on this page.
|
||||
|
||||
### LLVM
|
||||
**version: 10.0.x**
|
||||
|
|
|
@ -32,6 +32,12 @@ members = [
|
|||
"roc_std",
|
||||
"docs"
|
||||
]
|
||||
# Needed to be able to run `cargo run -p roc_cli --no-default-features` -
|
||||
# see www/build.sh for more.
|
||||
#
|
||||
# Without the `-p` flag, cargo ignores `--no-default-features` when you have a
|
||||
# workspace, and without `resolver = "2"` here, you can't use `-p` like this.
|
||||
resolver = "2"
|
||||
|
||||
# Optimizations based on https://deterministic.space/high-performance-rust.html
|
||||
[profile.release]
|
||||
|
|
|
@ -15,7 +15,12 @@ test = false
|
|||
bench = false
|
||||
|
||||
[features]
|
||||
default = ["target-x86"]
|
||||
default = ["target-x86", "llvm", "editor"]
|
||||
|
||||
# This is a separate feature because when we generate docs on Netlify,
|
||||
# it doesn't have LLVM installed. (Also, it doesn't need to do code gen.)
|
||||
llvm = ["inkwell", "roc_gen", "roc_build/llvm"]
|
||||
editor = ["roc_editor"]
|
||||
|
||||
target-x86 = []
|
||||
|
||||
|
@ -45,11 +50,11 @@ roc_unify = { path = "../compiler/unify" }
|
|||
roc_solve = { path = "../compiler/solve" }
|
||||
roc_mono = { path = "../compiler/mono" }
|
||||
roc_load = { path = "../compiler/load" }
|
||||
roc_gen = { path = "../compiler/gen" }
|
||||
roc_build = { path = "../compiler/build" }
|
||||
roc_gen = { path = "../compiler/gen", optional = true }
|
||||
roc_build = { path = "../compiler/build", default-features = false }
|
||||
roc_fmt = { path = "../compiler/fmt" }
|
||||
roc_reporting = { path = "../compiler/reporting" }
|
||||
roc_editor = { path = "../editor" }
|
||||
roc_editor = { path = "../editor", optional = true }
|
||||
# TODO switch to clap 3.0.0 once it's out. Tried adding clap = "~3.0.0-beta.1" and cargo wouldn't accept it
|
||||
clap = { git = "https://github.com/rtfeldman/clap", branch = "master" }
|
||||
const_format = "0.2.8"
|
||||
|
@ -62,7 +67,7 @@ inlinable_string = "0.1"
|
|||
libc = "0.2"
|
||||
libloading = "0.6"
|
||||
|
||||
inkwell = { path = "../vendor/inkwell" }
|
||||
inkwell = { path = "../vendor/inkwell", optional = true }
|
||||
target-lexicon = "0.10"
|
||||
tempfile = "3.1.0"
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ use roc_build::{
|
|||
};
|
||||
use roc_can::builtins::builtin_defs_map;
|
||||
use roc_collections::all::MutMap;
|
||||
use roc_gen::llvm::build::OptLevel;
|
||||
use roc_load::file::LoadingProblem;
|
||||
use roc_mono::ir::OptLevel;
|
||||
use std::path::PathBuf;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use target_lexicon::Triple;
|
||||
|
@ -32,6 +32,7 @@ pub struct BuiltFile {
|
|||
pub total_time: Duration,
|
||||
}
|
||||
|
||||
#[cfg(feature = "llvm")]
|
||||
pub fn build_file<'a>(
|
||||
arena: &'a Bump,
|
||||
target: &Triple,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#[macro_use]
|
||||
extern crate clap;
|
||||
|
||||
use build::{build_file, BuildOutcome, BuiltFile};
|
||||
use build::{BuildOutcome, BuiltFile};
|
||||
use bumpalo::Bump;
|
||||
use clap::{App, AppSettings, Arg, ArgMatches};
|
||||
use roc_build::link::LinkType;
|
||||
use roc_gen::llvm::build::OptLevel;
|
||||
use roc_load::file::LoadingProblem;
|
||||
use roc_mono::ir::OptLevel;
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -116,7 +116,9 @@ pub enum BuildConfig {
|
|||
BuildAndRun { roc_file_arg_index: usize },
|
||||
}
|
||||
|
||||
#[cfg(feature = "llvm")]
|
||||
pub fn build(target: &Triple, matches: &ArgMatches, config: BuildConfig) -> io::Result<i32> {
|
||||
use build::build_file;
|
||||
use BuildConfig::*;
|
||||
|
||||
let arena = Bump::new();
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
use roc_cli::{
|
||||
build, build_app, docs, repl, BuildConfig, CMD_BUILD, CMD_DOCS, CMD_EDIT, CMD_REPL, CMD_RUN,
|
||||
build_app, docs, repl, BuildConfig, CMD_BUILD, CMD_DOCS, CMD_EDIT, CMD_REPL, CMD_RUN,
|
||||
DIRECTORY_OR_FILES, ROC_FILE,
|
||||
};
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use target_lexicon::Triple;
|
||||
|
||||
#[cfg(feature = "llvm")]
|
||||
use roc_cli::build;
|
||||
|
||||
#[cfg(not(feature = "llvm"))]
|
||||
fn build(_target: &Triple, _matches: &clap::ArgMatches, _config: BuildConfig) -> io::Result<i32> {
|
||||
panic!("Building without LLVM is not currently supported.");
|
||||
}
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let matches = build_app().get_matches();
|
||||
|
||||
let exit_code = match matches.subcommand_name() {
|
||||
None => {
|
||||
roc_editor::launch(&[])?;
|
||||
launch_editor(&[])?;
|
||||
|
||||
// rustc couldn't infer the error type here
|
||||
Result::<i32, io::Error>::Ok(0)
|
||||
|
@ -44,14 +52,14 @@ fn main() -> io::Result<()> {
|
|||
.values_of_os(DIRECTORY_OR_FILES)
|
||||
{
|
||||
None => {
|
||||
roc_editor::launch(&[])?;
|
||||
launch_editor(&[])?;
|
||||
}
|
||||
Some(values) => {
|
||||
let paths = values
|
||||
.map(|os_str| Path::new(os_str))
|
||||
.collect::<Vec<&Path>>();
|
||||
|
||||
roc_editor::launch(&paths)?;
|
||||
launch_editor(&paths)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,3 +86,13 @@ fn main() -> io::Result<()> {
|
|||
|
||||
std::process::exit(exit_code);
|
||||
}
|
||||
|
||||
#[cfg(feature = "editor")]
|
||||
fn launch_editor(filepaths: &[&Path]) -> io::Result<()> {
|
||||
roc_editor::launch(filepaths)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "editor"))]
|
||||
fn launch_editor(_filepaths: &[&Path]) -> io::Result<()> {
|
||||
panic!("Cannot launch the editor because this build of roc did not include `feature = \"editor\"`!");
|
||||
}
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
use const_format::concatcp;
|
||||
#[cfg(feature = "llvm")]
|
||||
use gen::{gen_and_eval, ReplOutput};
|
||||
use roc_gen::llvm::build::OptLevel;
|
||||
use roc_parse::parser::{EExpr, SyntaxError};
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::highlight::{Highlighter, PromptInfo};
|
||||
use rustyline::validate::{self, ValidationContext, ValidationResult, Validator};
|
||||
use rustyline::Editor;
|
||||
use rustyline_derive::{Completer, Helper, Hinter};
|
||||
use std::borrow::Cow;
|
||||
use std::io;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
const BLUE: &str = "\u{001b}[36m";
|
||||
const PINK: &str = "\u{001b}[35m";
|
||||
|
@ -30,7 +27,9 @@ pub const INSTRUCTIONS: &str = "Enter an expression, or :help, or :exit/:q.\n";
|
|||
pub const PROMPT: &str = concatcp!("\n", BLUE, "»", END_COL, " ");
|
||||
pub const CONT_PROMPT: &str = concatcp!(BLUE, "…", END_COL, " ");
|
||||
|
||||
#[cfg(feature = "llvm")]
|
||||
mod eval;
|
||||
#[cfg(feature = "llvm")]
|
||||
mod gen;
|
||||
|
||||
#[derive(Completer, Helper, Hinter)]
|
||||
|
@ -107,7 +106,16 @@ impl Validator for InputValidator {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "llvm"))]
|
||||
pub fn main() -> io::Result<()> {
|
||||
panic!("The REPL currently requires being built with LLVM.");
|
||||
}
|
||||
|
||||
#[cfg(feature = "llvm")]
|
||||
pub fn main() -> io::Result<()> {
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::Editor;
|
||||
|
||||
// To debug rustyline:
|
||||
// <UNCOMMENT> env_logger::init();
|
||||
// <RUN WITH:> RUST_LOG=rustyline=debug cargo run repl 2> debug.log
|
||||
|
@ -226,7 +234,11 @@ fn report_parse_error(fail: SyntaxError) {
|
|||
println!("TODO Gracefully report parse error in repl: {:?}", fail);
|
||||
}
|
||||
|
||||
#[cfg(feature = "llvm")]
|
||||
fn eval_and_format<'a>(src: &str) -> Result<String, SyntaxError<'a>> {
|
||||
use roc_mono::ir::OptLevel;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
gen_and_eval(src.as_bytes(), Triple::host(), OptLevel::Normal).map(|output| match output {
|
||||
ReplOutput::NoProblems { expr, expr_type } => {
|
||||
format!("\n{} {}:{} {}", expr, PINK, END_COL, expr_type)
|
||||
|
|
|
@ -8,9 +8,9 @@ use roc_can::builtins::builtin_defs_map;
|
|||
use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_fmt::annotation::Formattable;
|
||||
use roc_fmt::annotation::{Newlines, Parens};
|
||||
use roc_gen::llvm::build::OptLevel;
|
||||
use roc_gen::llvm::externs::add_default_roc_externs;
|
||||
use roc_load::file::LoadingProblem;
|
||||
use roc_mono::ir::OptLevel;
|
||||
use roc_parse::parser::SyntaxError;
|
||||
use roc_types::pretty_print::{content_to_string, name_all_type_vars};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
|
|
@ -19,7 +19,7 @@ roc_unify = { path = "../unify" }
|
|||
roc_solve = { path = "../solve" }
|
||||
roc_mono = { path = "../mono" }
|
||||
roc_load = { path = "../load" }
|
||||
roc_gen = { path = "../gen" }
|
||||
roc_gen = { path = "../gen", optional = true }
|
||||
roc_reporting = { path = "../reporting" }
|
||||
im = "14" # im and im-rc should always have the same version!
|
||||
im-rc = "14" # im and im-rc should always have the same version!
|
||||
|
@ -28,7 +28,7 @@ inlinable_string = "0.1.0"
|
|||
libloading = "0.6"
|
||||
tempfile = "3.1.0"
|
||||
serde_json = "1.0"
|
||||
inkwell = { path = "../../vendor/inkwell" }
|
||||
inkwell = { path = "../../vendor/inkwell", optional = true }
|
||||
target-lexicon = "0.10"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -39,6 +39,10 @@ quickcheck = "0.8"
|
|||
quickcheck_macros = "0.8"
|
||||
|
||||
[features]
|
||||
default = ["llvm"]
|
||||
target-arm = []
|
||||
target-aarch64 = []
|
||||
target-webassembly = []
|
||||
# This is a separate feature because when we generate docs on Netlify,
|
||||
# it doesn't have LLVM installed. (Also, it doesn't need to do code gen.)
|
||||
llvm = ["inkwell", "roc_gen"]
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
use crate::target;
|
||||
use crate::target::arch_str;
|
||||
use inkwell::module::Module;
|
||||
use inkwell::targets::{CodeModel, FileType, RelocMode};
|
||||
#[cfg(feature = "llvm")]
|
||||
use libloading::{Error, Library};
|
||||
use roc_gen::llvm::build::OptLevel;
|
||||
#[cfg(feature = "llvm")]
|
||||
use roc_mono::ir::OptLevel;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Child, Command, Output};
|
||||
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
||||
use tempfile::tempdir;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum LinkType {
|
||||
|
@ -360,6 +358,9 @@ fn link_linux(
|
|||
};
|
||||
|
||||
let env_path = env::var("PATH").unwrap_or_else(|_| "".to_string());
|
||||
|
||||
init_arch(target);
|
||||
|
||||
// NOTE: order of arguments to `ld` matters here!
|
||||
// The `-l` flags should go after the `.o` arguments
|
||||
Ok((
|
||||
|
@ -477,12 +478,16 @@ fn link_macos(
|
|||
))
|
||||
}
|
||||
|
||||
#[cfg(feature = "llvm")]
|
||||
pub fn module_to_dylib(
|
||||
module: &Module,
|
||||
module: &inkwell::module::Module,
|
||||
target: &Triple,
|
||||
opt_level: OptLevel,
|
||||
) -> Result<Library, Error> {
|
||||
let dir = tempdir().unwrap();
|
||||
use crate::target::{self, convert_opt_level};
|
||||
use inkwell::targets::{CodeModel, FileType, RelocMode};
|
||||
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let filename = PathBuf::from("Test.roc");
|
||||
let file_path = dir.path().join(filename);
|
||||
let mut app_o_file = file_path;
|
||||
|
@ -492,7 +497,8 @@ pub fn module_to_dylib(
|
|||
// Emit the .o file using position-indepedent code (PIC) - needed for dylibs
|
||||
let reloc = RelocMode::PIC;
|
||||
let model = CodeModel::Default;
|
||||
let target_machine = target::target_machine(target, opt_level.into(), reloc, model).unwrap();
|
||||
let target_machine =
|
||||
target::target_machine(target, convert_opt_level(opt_level), reloc, model).unwrap();
|
||||
|
||||
target_machine
|
||||
.write_to_file(module, FileType::Object, &app_o_file)
|
||||
|
@ -529,3 +535,13 @@ fn validate_output(file_name: &str, cmd_name: &str, output: Output) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "llvm")]
|
||||
fn init_arch(target: &Triple) {
|
||||
crate::target::init_arch(target);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "llvm"))]
|
||||
fn init_arch(_target: &Triple) {
|
||||
panic!("Tried to initialize LLVM when crate was not built with `feature = \"llvm\"` enabled");
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
use crate::target;
|
||||
use bumpalo::Bump;
|
||||
use inkwell::context::Context;
|
||||
use inkwell::targets::{CodeModel, FileType, RelocMode};
|
||||
#[cfg(feature = "llvm")]
|
||||
use roc_gen::llvm::build::module_from_builtins;
|
||||
#[cfg(feature = "llvm")]
|
||||
pub use roc_gen::llvm::build::FunctionIterator;
|
||||
use roc_gen::llvm::build::{module_from_builtins, OptLevel};
|
||||
#[cfg(feature = "llvm")]
|
||||
use roc_load::file::MonomorphizedModule;
|
||||
#[cfg(feature = "llvm")]
|
||||
use roc_mono::ir::OptLevel;
|
||||
#[cfg(feature = "llvm")]
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::{Duration, SystemTime};
|
||||
use target_lexicon::Triple;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct CodeGenTiming {
|
||||
|
@ -18,16 +19,24 @@ pub struct CodeGenTiming {
|
|||
// TODO how should imported modules factor into this? What if those use builtins too?
|
||||
// TODO this should probably use more helper functions
|
||||
// TODO make this polymorphic in the llvm functions so it can be reused for another backend.
|
||||
#[cfg(feature = "llvm")]
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
pub fn gen_from_mono_module(
|
||||
arena: &Bump,
|
||||
arena: &bumpalo::Bump,
|
||||
mut loaded: MonomorphizedModule,
|
||||
roc_file_path: &Path,
|
||||
target: Triple,
|
||||
target: target_lexicon::Triple,
|
||||
app_o_file: &Path,
|
||||
opt_level: OptLevel,
|
||||
emit_debug_info: bool,
|
||||
) -> CodeGenTiming {
|
||||
use crate::target::{self, convert_opt_level};
|
||||
use inkwell::attributes::{Attribute, AttributeLoc};
|
||||
use inkwell::context::Context;
|
||||
use inkwell::module::Linkage;
|
||||
use inkwell::targets::{CodeModel, FileType, RelocMode};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use roc_reporting::report::{
|
||||
can_problem, mono_problem, type_problem, RocDocAllocator, DEFAULT_PALETTE,
|
||||
};
|
||||
|
@ -87,9 +96,6 @@ pub fn gen_from_mono_module(
|
|||
// module.strip_debug_info();
|
||||
|
||||
// mark our zig-defined builtins as internal
|
||||
use inkwell::attributes::{Attribute, AttributeLoc};
|
||||
use inkwell::module::Linkage;
|
||||
|
||||
let app_ll_file = {
|
||||
let mut temp = PathBuf::from(roc_file_path);
|
||||
temp.set_extension("ll");
|
||||
|
@ -226,7 +232,7 @@ pub fn gen_from_mono_module(
|
|||
let reloc = RelocMode::Default;
|
||||
let model = CodeModel::Default;
|
||||
let target_machine =
|
||||
target::target_machine(&target, opt_level.into(), reloc, model).unwrap();
|
||||
target::target_machine(&target, convert_opt_level(opt_level), reloc, model).unwrap();
|
||||
|
||||
target_machine
|
||||
.write_to_file(&env.module, FileType::Object, &app_o_file)
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use inkwell::targets::{
|
||||
CodeModel, InitializationConfig, RelocMode, Target, TargetMachine, TargetTriple,
|
||||
#[cfg(feature = "llvm")]
|
||||
use inkwell::{
|
||||
targets::{CodeModel, InitializationConfig, RelocMode, Target, TargetMachine, TargetTriple},
|
||||
OptimizationLevel,
|
||||
};
|
||||
use inkwell::OptimizationLevel;
|
||||
#[cfg(feature = "llvm")]
|
||||
use roc_mono::ir::OptLevel;
|
||||
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
||||
|
||||
pub fn target_triple_str(target: &Triple) -> &'static str {
|
||||
|
@ -28,36 +31,20 @@ pub fn target_triple_str(target: &Triple) -> &'static str {
|
|||
}
|
||||
}
|
||||
|
||||
/// NOTE: arch_str is *not* the same as the beginning of the magic target triple
|
||||
/// string! For example, if it's "x86-64" here, the magic target triple string
|
||||
/// will begin with "x86_64" (with an underscore) instead.
|
||||
pub fn arch_str(target: &Triple) -> &'static str {
|
||||
// Best guide I've found on how to determine these magic strings:
|
||||
//
|
||||
// https://stackoverflow.com/questions/15036909/clang-how-to-list-supported-target-architectures
|
||||
#[cfg(feature = "llvm")]
|
||||
pub fn init_arch(target: &Triple) {
|
||||
match target.architecture {
|
||||
Architecture::X86_64 => {
|
||||
Target::initialize_x86(&InitializationConfig::default());
|
||||
|
||||
"x86-64"
|
||||
}
|
||||
Architecture::Aarch64(_) if cfg!(feature = "target-aarch64") => {
|
||||
Target::initialize_aarch64(&InitializationConfig::default());
|
||||
"aarch64"
|
||||
}
|
||||
Architecture::Arm(_) if cfg!(feature = "target-arm") => {
|
||||
// NOTE: why not enable arm and wasm by default?
|
||||
//
|
||||
// We had some trouble getting them to link properly. This may be resolved in the
|
||||
// future, or maybe it was just some weird configuration on one machine.
|
||||
Target::initialize_arm(&InitializationConfig::default());
|
||||
|
||||
"arm"
|
||||
}
|
||||
Architecture::Wasm32 if cfg!(feature = "target-webassembly") => {
|
||||
Target::initialize_webassembly(&InitializationConfig::default());
|
||||
|
||||
"wasm32"
|
||||
}
|
||||
_ => panic!(
|
||||
"TODO gracefully handle unsupported target architecture: {:?}",
|
||||
|
@ -66,6 +53,26 @@ pub fn arch_str(target: &Triple) -> &'static str {
|
|||
}
|
||||
}
|
||||
|
||||
/// NOTE: arch_str is *not* the same as the beginning of the magic target triple
|
||||
/// string! For example, if it's "x86-64" here, the magic target triple string
|
||||
/// will begin with "x86_64" (with an underscore) instead.
|
||||
pub fn arch_str(target: &Triple) -> &'static str {
|
||||
// Best guide I've found on how to determine these magic strings:
|
||||
//
|
||||
// https://stackoverflow.com/questions/15036909/clang-how-to-list-supported-target-architectures
|
||||
match target.architecture {
|
||||
Architecture::X86_64 => "x86-64",
|
||||
Architecture::Aarch64(_) if cfg!(feature = "target-aarch64") => "aarch64",
|
||||
Architecture::Arm(_) if cfg!(feature = "target-arm") => "arm",
|
||||
Architecture::Wasm32 if cfg!(feature = "target-webassembly") => "wasm32",
|
||||
_ => panic!(
|
||||
"TODO gracefully handle unsupported target architecture: {:?}",
|
||||
target.architecture
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "llvm")]
|
||||
pub fn target_machine(
|
||||
target: &Triple,
|
||||
opt: OptimizationLevel,
|
||||
|
@ -74,6 +81,8 @@ pub fn target_machine(
|
|||
) -> Option<TargetMachine> {
|
||||
let arch = arch_str(target);
|
||||
|
||||
init_arch(target);
|
||||
|
||||
Target::from_name(arch).unwrap().create_target_machine(
|
||||
&TargetTriple::create(target_triple_str(target)),
|
||||
"generic",
|
||||
|
@ -83,3 +92,11 @@ pub fn target_machine(
|
|||
model,
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "llvm")]
|
||||
pub fn convert_opt_level(level: OptLevel) -> OptimizationLevel {
|
||||
match level {
|
||||
OptLevel::Normal => OptimizationLevel::None,
|
||||
OptLevel::Optimize => OptimizationLevel::Aggressive,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const Builder = std.build.Builder;
|
||||
|
||||
pub fn build(b: *Builder) void {
|
||||
// b.setPreferredReleaseMode(builtin.Mode.Debug);
|
||||
b.setPreferredReleaseMode(builtin.Mode.ReleaseFast);
|
||||
// b.setPreferredReleaseMode(builtin.Mode.Debug
|
||||
b.setPreferredReleaseMode(.ReleaseFast);
|
||||
const mode = b.standardReleaseOptions();
|
||||
|
||||
// Options
|
||||
const fallback_main_path = "./src/main.zig";
|
||||
const main_path_desc = b.fmt("Override path to main.zig. Used by \"ir\" and \"test\". Defaults to \"{}\". ", .{fallback_main_path});
|
||||
const main_path_desc = b.fmt("Override path to main.zig. Used by \"ir\" and \"test\". Defaults to \"{s}\". ", .{fallback_main_path});
|
||||
const main_path = b.option([]const u8, "main-path", main_path_desc) orelse fallback_main_path;
|
||||
|
||||
// Tests
|
||||
|
|
|
@ -17,7 +17,7 @@ pub const RocDec = struct {
|
|||
pub const one_point_zero: comptime RocDec = .{ .num = one_point_zero_i128 };
|
||||
|
||||
pub fn fromU64(num: u64) RocDec {
|
||||
return .{ .num = @intCast(i128, num) * one_point_zero_i128 };
|
||||
return .{ .num = num * one_point_zero_i128 };
|
||||
}
|
||||
|
||||
pub fn fromString(roc_str: RocStr) ?RocDec {
|
||||
|
@ -379,112 +379,112 @@ const expect = testing.expect;
|
|||
test "fromU64" {
|
||||
var dec = RocDec.fromU64(25);
|
||||
|
||||
expectEqual(RocDec{ .num = 25000000000000000000 }, dec);
|
||||
try expectEqual(RocDec{ .num = 25000000000000000000 }, dec);
|
||||
}
|
||||
|
||||
test "fromString: empty" {
|
||||
var roc_str = RocStr.init("", 0);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(dec, null);
|
||||
try expectEqual(dec, null);
|
||||
}
|
||||
|
||||
test "fromString: 0" {
|
||||
var roc_str = RocStr.init("0", 1);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(RocDec{ .num = 0 }, dec.?);
|
||||
try expectEqual(RocDec{ .num = 0 }, dec.?);
|
||||
}
|
||||
|
||||
test "fromString: 1" {
|
||||
var roc_str = RocStr.init("1", 1);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(RocDec.one_point_zero, dec.?);
|
||||
try expectEqual(RocDec.one_point_zero, dec.?);
|
||||
}
|
||||
|
||||
test "fromString: 123.45" {
|
||||
var roc_str = RocStr.init("123.45", 6);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(RocDec{ .num = 123450000000000000000 }, dec.?);
|
||||
try expectEqual(RocDec{ .num = 123450000000000000000 }, dec.?);
|
||||
}
|
||||
|
||||
test "fromString: .45" {
|
||||
var roc_str = RocStr.init(".45", 3);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(RocDec{ .num = 450000000000000000 }, dec.?);
|
||||
try expectEqual(RocDec{ .num = 450000000000000000 }, dec.?);
|
||||
}
|
||||
|
||||
test "fromString: 0.45" {
|
||||
var roc_str = RocStr.init("0.45", 4);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(RocDec{ .num = 450000000000000000 }, dec.?);
|
||||
try expectEqual(RocDec{ .num = 450000000000000000 }, dec.?);
|
||||
}
|
||||
|
||||
test "fromString: 123" {
|
||||
var roc_str = RocStr.init("123", 3);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(RocDec{ .num = 123000000000000000000 }, dec.?);
|
||||
try expectEqual(RocDec{ .num = 123000000000000000000 }, dec.?);
|
||||
}
|
||||
|
||||
test "fromString: -.45" {
|
||||
var roc_str = RocStr.init("-.45", 4);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(RocDec{ .num = -450000000000000000 }, dec.?);
|
||||
try expectEqual(RocDec{ .num = -450000000000000000 }, dec.?);
|
||||
}
|
||||
|
||||
test "fromString: -0.45" {
|
||||
var roc_str = RocStr.init("-0.45", 5);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(RocDec{ .num = -450000000000000000 }, dec.?);
|
||||
try expectEqual(RocDec{ .num = -450000000000000000 }, dec.?);
|
||||
}
|
||||
|
||||
test "fromString: -123" {
|
||||
var roc_str = RocStr.init("-123", 4);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(RocDec{ .num = -123000000000000000000 }, dec.?);
|
||||
try expectEqual(RocDec{ .num = -123000000000000000000 }, dec.?);
|
||||
}
|
||||
|
||||
test "fromString: -123.45" {
|
||||
var roc_str = RocStr.init("-123.45", 7);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(RocDec{ .num = -123450000000000000000 }, dec.?);
|
||||
try expectEqual(RocDec{ .num = -123450000000000000000 }, dec.?);
|
||||
}
|
||||
|
||||
test "fromString: abc" {
|
||||
var roc_str = RocStr.init("abc", 3);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(dec, null);
|
||||
try expectEqual(dec, null);
|
||||
}
|
||||
|
||||
test "fromString: 123.abc" {
|
||||
var roc_str = RocStr.init("123.abc", 7);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(dec, null);
|
||||
try expectEqual(dec, null);
|
||||
}
|
||||
|
||||
test "fromString: abc.123" {
|
||||
var roc_str = RocStr.init("abc.123", 7);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(dec, null);
|
||||
try expectEqual(dec, null);
|
||||
}
|
||||
|
||||
test "fromString: .123.1" {
|
||||
var roc_str = RocStr.init(".123.1", 6);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
|
||||
expectEqual(dec, null);
|
||||
try expectEqual(dec, null);
|
||||
}
|
||||
|
||||
test "toString: 123.45" {
|
||||
|
@ -560,29 +560,29 @@ test "toString: 123.111111111111 (big str)" {
|
|||
test "add: 0" {
|
||||
var dec: RocDec = .{ .num = 0 };
|
||||
|
||||
expectEqual(RocDec{ .num = 0 }, dec.add(.{ .num = 0 }));
|
||||
try expectEqual(RocDec{ .num = 0 }, dec.add(.{ .num = 0 }));
|
||||
}
|
||||
|
||||
test "add: 1" {
|
||||
var dec: RocDec = .{ .num = 0 };
|
||||
|
||||
expectEqual(RocDec{ .num = 1 }, dec.add(.{ .num = 1 }));
|
||||
try expectEqual(RocDec{ .num = 1 }, dec.add(.{ .num = 1 }));
|
||||
}
|
||||
|
||||
test "mul: by 0" {
|
||||
var dec: RocDec = .{ .num = 0 };
|
||||
|
||||
expectEqual(RocDec{ .num = 0 }, dec.mul(.{ .num = 0 }));
|
||||
try expectEqual(RocDec{ .num = 0 }, dec.mul(.{ .num = 0 }));
|
||||
}
|
||||
|
||||
test "mul: by 1" {
|
||||
var dec: RocDec = RocDec.fromU64(15);
|
||||
|
||||
expectEqual(RocDec.fromU64(15), dec.mul(RocDec.fromU64(1)));
|
||||
try expectEqual(RocDec.fromU64(15), dec.mul(RocDec.fromU64(1)));
|
||||
}
|
||||
|
||||
test "mul: by 2" {
|
||||
var dec: RocDec = RocDec.fromU64(15);
|
||||
|
||||
expectEqual(RocDec.fromU64(30), dec.mul(RocDec.fromU64(2)));
|
||||
try expectEqual(RocDec.fromU64(30), dec.mul(RocDec.fromU64(2)));
|
||||
}
|
||||
|
|
|
@ -202,13 +202,13 @@ const expectEqual = std.testing.expectEqual;
|
|||
test "test vectors" {
|
||||
const hash = Wyhash.hash;
|
||||
|
||||
expectEqual(hash(0, ""), 0x0);
|
||||
expectEqual(hash(1, "a"), 0xbed235177f41d328);
|
||||
expectEqual(hash(2, "abc"), 0xbe348debe59b27c3);
|
||||
expectEqual(hash(3, "message digest"), 0x37320f657213a290);
|
||||
expectEqual(hash(4, "abcdefghijklmnopqrstuvwxyz"), 0xd0b270e1d8a7019c);
|
||||
expectEqual(hash(5, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0x602a1894d3bbfe7f);
|
||||
expectEqual(hash(6, "12345678901234567890123456789012345678901234567890123456789012345678901234567890"), 0x829e9c148b75970e);
|
||||
try expectEqual(hash(0, ""), 0x0);
|
||||
try expectEqual(hash(1, "a"), 0xbed235177f41d328);
|
||||
try expectEqual(hash(2, "abc"), 0xbe348debe59b27c3);
|
||||
try expectEqual(hash(3, "message digest"), 0x37320f657213a290);
|
||||
try expectEqual(hash(4, "abcdefghijklmnopqrstuvwxyz"), 0xd0b270e1d8a7019c);
|
||||
try expectEqual(hash(5, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0x602a1894d3bbfe7f);
|
||||
try expectEqual(hash(6, "12345678901234567890123456789012345678901234567890123456789012345678901234567890"), 0x829e9c148b75970e);
|
||||
}
|
||||
|
||||
test "test vectors streaming" {
|
||||
|
@ -216,19 +216,19 @@ test "test vectors streaming" {
|
|||
for ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") |e| {
|
||||
wh.update(mem.asBytes(&e));
|
||||
}
|
||||
expectEqual(wh.final(), 0x602a1894d3bbfe7f);
|
||||
try expectEqual(wh.final(), 0x602a1894d3bbfe7f);
|
||||
|
||||
const pattern = "1234567890";
|
||||
const count = 8;
|
||||
const result = 0x829e9c148b75970e;
|
||||
expectEqual(Wyhash.hash(6, pattern ** 8), result);
|
||||
try expectEqual(Wyhash.hash(6, pattern ** 8), result);
|
||||
|
||||
wh = Wyhash.init(6);
|
||||
var i: u32 = 0;
|
||||
while (i < count) : (i += 1) {
|
||||
wh.update(pattern);
|
||||
}
|
||||
expectEqual(wh.final(), result);
|
||||
try expectEqual(wh.final(), result);
|
||||
}
|
||||
|
||||
test "iterative non-divisible update" {
|
||||
|
@ -250,6 +250,6 @@ test "iterative non-divisible update" {
|
|||
}
|
||||
const iterative_hash = wy.final();
|
||||
|
||||
std.testing.expectEqual(iterative_hash, non_iterative_hash);
|
||||
try std.testing.expectEqual(iterative_hash, non_iterative_hash);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ pub const BoundClass = enum(u8) {
|
|||
};
|
||||
|
||||
test "Bound Class" {
|
||||
expectEqual(0, @enumToInt(BoundClass.START));
|
||||
try expectEqual(0, @enumToInt(BoundClass.START));
|
||||
}
|
||||
|
||||
// https://github.com/JuliaStrings/utf8proc/blob/master/utf8proc.c#L261
|
||||
|
@ -112,7 +112,7 @@ fn unsafeCodepointToBoundClass(codepoint: u21) *const BoundClass {
|
|||
}
|
||||
|
||||
test "unsafeCodepointToBoundClass: valid" {
|
||||
expectEqual(BoundClass.CONTROL, unsafeCodepointToBoundClass(8).*);
|
||||
try expectEqual(BoundClass.CONTROL, unsafeCodepointToBoundClass(8).*);
|
||||
}
|
||||
|
||||
// https://github.com/JuliaStrings/utf8proc/blob/master/utf8proc.c#L242
|
||||
|
@ -125,11 +125,11 @@ fn codepointToBoundClass(codepoint: u21) *const BoundClass {
|
|||
}
|
||||
|
||||
test "codepointToBoundClass: valid" {
|
||||
expectEqual(BoundClass.CONTROL, codepointToBoundClass(8).*);
|
||||
try expectEqual(BoundClass.CONTROL, codepointToBoundClass(8).*);
|
||||
}
|
||||
|
||||
test "codepointToBoundClass: invalid" {
|
||||
expectEqual(BoundClass.OTHER, codepointToBoundClass(codepoint_max + 5).*);
|
||||
try expectEqual(BoundClass.OTHER, codepointToBoundClass(codepoint_max + 5).*);
|
||||
}
|
||||
|
||||
// https://github.com/JuliaStrings/utf8proc/blob/master/utf8proc.c#L319
|
||||
|
|
|
@ -781,43 +781,19 @@ pub fn listDrop(
|
|||
}
|
||||
|
||||
pub fn listRange(width: utils.IntWidth, low: Opaque, high: Opaque) callconv(.C) RocList {
|
||||
const IntWidth = utils.IntWidth;
|
||||
|
||||
switch (width) {
|
||||
IntWidth.U8 => {
|
||||
return helper1(u8, low, high);
|
||||
},
|
||||
IntWidth.U16 => {
|
||||
return helper1(u16, low, high);
|
||||
},
|
||||
IntWidth.U32 => {
|
||||
return helper1(u32, low, high);
|
||||
},
|
||||
IntWidth.U64 => {
|
||||
return helper1(u64, low, high);
|
||||
},
|
||||
IntWidth.U128 => {
|
||||
return helper1(u128, low, high);
|
||||
},
|
||||
IntWidth.I8 => {
|
||||
return helper1(i8, low, high);
|
||||
},
|
||||
IntWidth.I16 => {
|
||||
return helper1(i16, low, high);
|
||||
},
|
||||
IntWidth.I32 => {
|
||||
return helper1(i32, low, high);
|
||||
},
|
||||
IntWidth.I64 => {
|
||||
return helper1(i64, low, high);
|
||||
},
|
||||
IntWidth.I128 => {
|
||||
return helper1(i128, low, high);
|
||||
},
|
||||
IntWidth.Usize => {
|
||||
return helper1(usize, low, high);
|
||||
},
|
||||
}
|
||||
return switch (width) {
|
||||
.U8 => helper1(u8, low, high),
|
||||
.U16 => helper1(u16, low, high),
|
||||
.U32 => helper1(u32, low, high),
|
||||
.U64 => helper1(u64, low, high),
|
||||
.U128 => helper1(u128, low, high),
|
||||
.I8 => helper1(i8, low, high),
|
||||
.I16 => helper1(i16, low, high),
|
||||
.I32 => helper1(i32, low, high),
|
||||
.I64 => helper1(i64, low, high),
|
||||
.I128 => helper1(i128, low, high),
|
||||
.Usize => helper1(usize, low, high),
|
||||
};
|
||||
}
|
||||
|
||||
fn helper1(comptime T: type, low: Opaque, high: Opaque) RocList {
|
||||
|
|
|
@ -273,7 +273,7 @@ pub const RocStr = extern struct {
|
|||
const str2_ptr: [*]u8 = &str2;
|
||||
var roc_str2 = RocStr.init(str2_ptr, str2_len);
|
||||
|
||||
expect(roc_str1.eq(roc_str2));
|
||||
try expect(roc_str1.eq(roc_str2));
|
||||
|
||||
roc_str1.deinit();
|
||||
roc_str2.deinit();
|
||||
|
@ -295,7 +295,7 @@ pub const RocStr = extern struct {
|
|||
roc_str2.deinit();
|
||||
}
|
||||
|
||||
expect(!roc_str1.eq(roc_str2));
|
||||
try expect(!roc_str1.eq(roc_str2));
|
||||
}
|
||||
|
||||
test "RocStr.eq: not equal same length" {
|
||||
|
@ -314,7 +314,7 @@ pub const RocStr = extern struct {
|
|||
roc_str2.deinit();
|
||||
}
|
||||
|
||||
expect(!roc_str1.eq(roc_str2));
|
||||
try expect(!roc_str1.eq(roc_str2));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -449,8 +449,8 @@ test "strSplitInPlace: no delimiter" {
|
|||
delimiter.deinit();
|
||||
}
|
||||
|
||||
expectEqual(array.len, expected.len);
|
||||
expect(array[0].eq(expected[0]));
|
||||
try expectEqual(array.len, expected.len);
|
||||
try expect(array[0].eq(expected[0]));
|
||||
}
|
||||
|
||||
test "strSplitInPlace: empty end" {
|
||||
|
@ -490,10 +490,10 @@ test "strSplitInPlace: empty end" {
|
|||
delimiter.deinit();
|
||||
}
|
||||
|
||||
expectEqual(array.len, expected.len);
|
||||
expect(array[0].eq(expected[0]));
|
||||
expect(array[1].eq(expected[1]));
|
||||
expect(array[2].eq(expected[2]));
|
||||
try expectEqual(array.len, expected.len);
|
||||
try expect(array[0].eq(expected[0]));
|
||||
try expect(array[1].eq(expected[1]));
|
||||
try expect(array[2].eq(expected[2]));
|
||||
}
|
||||
|
||||
test "strSplitInPlace: delimiter on sides" {
|
||||
|
@ -532,10 +532,10 @@ test "strSplitInPlace: delimiter on sides" {
|
|||
delimiter.deinit();
|
||||
}
|
||||
|
||||
expectEqual(array.len, expected.len);
|
||||
expect(array[0].eq(expected[0]));
|
||||
expect(array[1].eq(expected[1]));
|
||||
expect(array[2].eq(expected[2]));
|
||||
try expectEqual(array.len, expected.len);
|
||||
try expect(array[0].eq(expected[0]));
|
||||
try expect(array[1].eq(expected[1]));
|
||||
try expect(array[2].eq(expected[2]));
|
||||
}
|
||||
|
||||
test "strSplitInPlace: three pieces" {
|
||||
|
@ -573,10 +573,10 @@ test "strSplitInPlace: three pieces" {
|
|||
delimiter.deinit();
|
||||
}
|
||||
|
||||
expectEqual(expected_array.len, array.len);
|
||||
expect(array[0].eq(expected_array[0]));
|
||||
expect(array[1].eq(expected_array[1]));
|
||||
expect(array[2].eq(expected_array[2]));
|
||||
try expectEqual(expected_array.len, array.len);
|
||||
try expect(array[0].eq(expected_array[0]));
|
||||
try expect(array[1].eq(expected_array[1]));
|
||||
try expect(array[2].eq(expected_array[2]));
|
||||
}
|
||||
|
||||
// This is used for `Str.split : Str, Str -> Array Str
|
||||
|
@ -639,7 +639,7 @@ test "countSegments: long delimiter" {
|
|||
}
|
||||
|
||||
const segments_count = countSegments(str, delimiter);
|
||||
expectEqual(segments_count, 1);
|
||||
try expectEqual(segments_count, 1);
|
||||
}
|
||||
|
||||
test "countSegments: delimiter at start" {
|
||||
|
@ -658,7 +658,7 @@ test "countSegments: delimiter at start" {
|
|||
|
||||
const segments_count = countSegments(str, delimiter);
|
||||
|
||||
expectEqual(segments_count, 2);
|
||||
try expectEqual(segments_count, 2);
|
||||
}
|
||||
|
||||
test "countSegments: delimiter interspered" {
|
||||
|
@ -677,7 +677,7 @@ test "countSegments: delimiter interspered" {
|
|||
|
||||
const segments_count = countSegments(str, delimiter);
|
||||
|
||||
expectEqual(segments_count, 3);
|
||||
try expectEqual(segments_count, 3);
|
||||
}
|
||||
|
||||
// Str.countGraphemeClusters
|
||||
|
@ -721,7 +721,7 @@ fn rocStrFromLiteral(bytes_arr: *const []u8) RocStr {}
|
|||
|
||||
test "countGraphemeClusters: empty string" {
|
||||
const count = countGraphemeClusters(RocStr.empty());
|
||||
expectEqual(count, 0);
|
||||
try expectEqual(count, 0);
|
||||
}
|
||||
|
||||
test "countGraphemeClusters: ascii characters" {
|
||||
|
@ -731,7 +731,7 @@ test "countGraphemeClusters: ascii characters" {
|
|||
defer str.deinit();
|
||||
|
||||
const count = countGraphemeClusters(str);
|
||||
expectEqual(count, 4);
|
||||
try expectEqual(count, 4);
|
||||
}
|
||||
|
||||
test "countGraphemeClusters: utf8 characters" {
|
||||
|
@ -741,7 +741,7 @@ test "countGraphemeClusters: utf8 characters" {
|
|||
defer str.deinit();
|
||||
|
||||
const count = countGraphemeClusters(str);
|
||||
expectEqual(count, 3);
|
||||
try expectEqual(count, 3);
|
||||
}
|
||||
|
||||
test "countGraphemeClusters: emojis" {
|
||||
|
@ -751,7 +751,7 @@ test "countGraphemeClusters: emojis" {
|
|||
defer str.deinit();
|
||||
|
||||
const count = countGraphemeClusters(str);
|
||||
expectEqual(count, 3);
|
||||
try expectEqual(count, 3);
|
||||
}
|
||||
|
||||
test "countGraphemeClusters: emojis and ut8 characters" {
|
||||
|
@ -761,7 +761,7 @@ test "countGraphemeClusters: emojis and ut8 characters" {
|
|||
defer str.deinit();
|
||||
|
||||
const count = countGraphemeClusters(str);
|
||||
expectEqual(count, 6);
|
||||
try expectEqual(count, 6);
|
||||
}
|
||||
|
||||
test "countGraphemeClusters: emojis, ut8, and ascii characters" {
|
||||
|
@ -771,7 +771,7 @@ test "countGraphemeClusters: emojis, ut8, and ascii characters" {
|
|||
defer str.deinit();
|
||||
|
||||
const count = countGraphemeClusters(str);
|
||||
expectEqual(count, 10);
|
||||
try expectEqual(count, 10);
|
||||
}
|
||||
|
||||
// Str.startsWith
|
||||
|
@ -821,27 +821,27 @@ pub fn startsWithCodePoint(string: RocStr, prefix: u32) callconv(.C) bool {
|
|||
test "startsWithCodePoint: ascii char" {
|
||||
const whole = RocStr.init("foobar", 6);
|
||||
const prefix = 'f';
|
||||
expect(startsWithCodePoint(whole, prefix));
|
||||
try expect(startsWithCodePoint(whole, prefix));
|
||||
}
|
||||
|
||||
test "startsWithCodePoint: emoji" {
|
||||
const yes = RocStr.init("💖foobar", 10);
|
||||
const no = RocStr.init("foobar", 6);
|
||||
const prefix = '💖';
|
||||
expect(startsWithCodePoint(yes, prefix));
|
||||
expect(!startsWithCodePoint(no, prefix));
|
||||
try expect(startsWithCodePoint(yes, prefix));
|
||||
try expect(!startsWithCodePoint(no, prefix));
|
||||
}
|
||||
|
||||
test "startsWith: foo starts with fo" {
|
||||
const foo = RocStr.init("foo", 3);
|
||||
const fo = RocStr.init("fo", 2);
|
||||
expect(startsWith(foo, fo));
|
||||
try expect(startsWith(foo, fo));
|
||||
}
|
||||
|
||||
test "startsWith: 123456789123456789 starts with 123456789123456789" {
|
||||
const str = RocStr.init("123456789123456789", 18);
|
||||
defer str.deinit();
|
||||
expect(startsWith(str, str));
|
||||
try expect(startsWith(str, str));
|
||||
}
|
||||
|
||||
test "startsWith: 12345678912345678910 starts with 123456789123456789" {
|
||||
|
@ -850,7 +850,7 @@ test "startsWith: 12345678912345678910 starts with 123456789123456789" {
|
|||
const prefix = RocStr.init("123456789123456789", 18);
|
||||
defer prefix.deinit();
|
||||
|
||||
expect(startsWith(str, prefix));
|
||||
try expect(startsWith(str, prefix));
|
||||
}
|
||||
|
||||
// Str.endsWith
|
||||
|
@ -882,13 +882,13 @@ test "endsWith: foo ends with oo" {
|
|||
defer foo.deinit();
|
||||
defer oo.deinit();
|
||||
|
||||
expect(endsWith(foo, oo));
|
||||
try expect(endsWith(foo, oo));
|
||||
}
|
||||
|
||||
test "endsWith: 123456789123456789 ends with 123456789123456789" {
|
||||
const str = RocStr.init("123456789123456789", 18);
|
||||
defer str.deinit();
|
||||
expect(endsWith(str, str));
|
||||
try expect(endsWith(str, str));
|
||||
}
|
||||
|
||||
test "endsWith: 12345678912345678910 ends with 345678912345678910" {
|
||||
|
@ -897,7 +897,7 @@ test "endsWith: 12345678912345678910 ends with 345678912345678910" {
|
|||
defer str.deinit();
|
||||
defer suffix.deinit();
|
||||
|
||||
expect(endsWith(str, suffix));
|
||||
try expect(endsWith(str, suffix));
|
||||
}
|
||||
|
||||
test "endsWith: hello world ends with world" {
|
||||
|
@ -906,7 +906,7 @@ test "endsWith: hello world ends with world" {
|
|||
defer str.deinit();
|
||||
defer suffix.deinit();
|
||||
|
||||
expect(endsWith(str, suffix));
|
||||
try expect(endsWith(str, suffix));
|
||||
}
|
||||
|
||||
// Str.concat
|
||||
|
@ -978,7 +978,7 @@ test "RocStr.concat: small concat small" {
|
|||
|
||||
defer result.deinit();
|
||||
|
||||
expect(roc_str3.eq(result));
|
||||
try expect(roc_str3.eq(result));
|
||||
}
|
||||
|
||||
pub const RocListStr = extern struct {
|
||||
|
@ -1057,7 +1057,7 @@ test "RocStr.joinWith: result is big" {
|
|||
|
||||
defer result.deinit();
|
||||
|
||||
expect(roc_result.eq(result));
|
||||
try expect(roc_result.eq(result));
|
||||
}
|
||||
|
||||
// Str.toBytes
|
||||
|
@ -1191,8 +1191,8 @@ fn validateUtf8BytesX(str: RocList) FromUtf8Result {
|
|||
return fromUtf8(str);
|
||||
}
|
||||
|
||||
fn expectOk(result: FromUtf8Result) void {
|
||||
expectEqual(result.is_ok, true);
|
||||
fn expectOk(result: FromUtf8Result) !void {
|
||||
try expectEqual(result.is_ok, true);
|
||||
}
|
||||
|
||||
fn sliceHelp(bytes: [*]const u8, length: usize) RocList {
|
||||
|
@ -1217,7 +1217,7 @@ test "validateUtf8Bytes: ascii" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectOk(validateUtf8BytesX(list));
|
||||
try expectOk(validateUtf8BytesX(list));
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: unicode œ" {
|
||||
|
@ -1225,7 +1225,7 @@ test "validateUtf8Bytes: unicode œ" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectOk(validateUtf8BytesX(list));
|
||||
try expectOk(validateUtf8BytesX(list));
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: unicode ∆" {
|
||||
|
@ -1233,7 +1233,7 @@ test "validateUtf8Bytes: unicode ∆" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectOk(validateUtf8BytesX(list));
|
||||
try expectOk(validateUtf8BytesX(list));
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: emoji" {
|
||||
|
@ -1241,7 +1241,7 @@ test "validateUtf8Bytes: emoji" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectOk(validateUtf8BytesX(list));
|
||||
try expectOk(validateUtf8BytesX(list));
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: unicode ∆ in middle of array" {
|
||||
|
@ -1249,15 +1249,15 @@ test "validateUtf8Bytes: unicode ∆ in middle of array" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectOk(validateUtf8BytesX(list));
|
||||
try expectOk(validateUtf8BytesX(list));
|
||||
}
|
||||
|
||||
fn expectErr(list: RocList, index: usize, err: Utf8DecodeError, problem: Utf8ByteProblem) void {
|
||||
fn expectErr(list: RocList, index: usize, err: Utf8DecodeError, problem: Utf8ByteProblem) !void {
|
||||
const str_ptr = @ptrCast([*]u8, list.bytes);
|
||||
const str_len = list.length;
|
||||
|
||||
expectError(err, numberOfNextCodepointBytes(str_ptr, str_len, index));
|
||||
expectEqual(toErrUtf8ByteResponse(index, problem), validateUtf8Bytes(str_ptr, str_len));
|
||||
try expectError(err, numberOfNextCodepointBytes(str_ptr, str_len, index));
|
||||
try expectEqual(toErrUtf8ByteResponse(index, problem), validateUtf8Bytes(str_ptr, str_len));
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: invalid start byte" {
|
||||
|
@ -1266,7 +1266,7 @@ test "validateUtf8Bytes: invalid start byte" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectErr(list, 2, error.Utf8InvalidStartByte, Utf8ByteProblem.InvalidStartByte);
|
||||
try expectErr(list, 2, error.Utf8InvalidStartByte, Utf8ByteProblem.InvalidStartByte);
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: unexpected eof for 2 byte sequence" {
|
||||
|
@ -1275,7 +1275,7 @@ test "validateUtf8Bytes: unexpected eof for 2 byte sequence" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectErr(list, 3, error.UnexpectedEof, Utf8ByteProblem.UnexpectedEndOfSequence);
|
||||
try expectErr(list, 3, error.UnexpectedEof, Utf8ByteProblem.UnexpectedEndOfSequence);
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: expected continuation for 2 byte sequence" {
|
||||
|
@ -1284,7 +1284,7 @@ test "validateUtf8Bytes: expected continuation for 2 byte sequence" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectErr(list, 3, error.Utf8ExpectedContinuation, Utf8ByteProblem.ExpectedContinuation);
|
||||
try expectErr(list, 3, error.Utf8ExpectedContinuation, Utf8ByteProblem.ExpectedContinuation);
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: unexpected eof for 3 byte sequence" {
|
||||
|
@ -1293,7 +1293,7 @@ test "validateUtf8Bytes: unexpected eof for 3 byte sequence" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectErr(list, 3, error.UnexpectedEof, Utf8ByteProblem.UnexpectedEndOfSequence);
|
||||
try expectErr(list, 3, error.UnexpectedEof, Utf8ByteProblem.UnexpectedEndOfSequence);
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: expected continuation for 3 byte sequence" {
|
||||
|
@ -1302,7 +1302,7 @@ test "validateUtf8Bytes: expected continuation for 3 byte sequence" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectErr(list, 3, error.Utf8ExpectedContinuation, Utf8ByteProblem.ExpectedContinuation);
|
||||
try expectErr(list, 3, error.Utf8ExpectedContinuation, Utf8ByteProblem.ExpectedContinuation);
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: unexpected eof for 4 byte sequence" {
|
||||
|
@ -1311,7 +1311,7 @@ test "validateUtf8Bytes: unexpected eof for 4 byte sequence" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectErr(list, 3, error.UnexpectedEof, Utf8ByteProblem.UnexpectedEndOfSequence);
|
||||
try expectErr(list, 3, error.UnexpectedEof, Utf8ByteProblem.UnexpectedEndOfSequence);
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: expected continuation for 4 byte sequence" {
|
||||
|
@ -1320,7 +1320,7 @@ test "validateUtf8Bytes: expected continuation for 4 byte sequence" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectErr(list, 3, error.Utf8ExpectedContinuation, Utf8ByteProblem.ExpectedContinuation);
|
||||
try expectErr(list, 3, error.Utf8ExpectedContinuation, Utf8ByteProblem.ExpectedContinuation);
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: overlong" {
|
||||
|
@ -1329,7 +1329,7 @@ test "validateUtf8Bytes: overlong" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectErr(list, 3, error.Utf8OverlongEncoding, Utf8ByteProblem.OverlongEncoding);
|
||||
try expectErr(list, 3, error.Utf8OverlongEncoding, Utf8ByteProblem.OverlongEncoding);
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: codepoint out too large" {
|
||||
|
@ -1338,7 +1338,7 @@ test "validateUtf8Bytes: codepoint out too large" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectErr(list, 3, error.Utf8CodepointTooLarge, Utf8ByteProblem.CodepointTooLarge);
|
||||
try expectErr(list, 3, error.Utf8CodepointTooLarge, Utf8ByteProblem.CodepointTooLarge);
|
||||
}
|
||||
|
||||
test "validateUtf8Bytes: surrogate halves" {
|
||||
|
@ -1347,5 +1347,5 @@ test "validateUtf8Bytes: surrogate halves" {
|
|||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
expectErr(list, 3, error.Utf8EncodesSurrogateHalf, Utf8ByteProblem.EncodesSurrogateHalf);
|
||||
try expectErr(list, 3, error.Utf8EncodesSurrogateHalf, Utf8ByteProblem.EncodesSurrogateHalf);
|
||||
}
|
||||
|
|
|
@ -71,44 +71,6 @@ pub const IntWidth = enum(u8) {
|
|||
Usize,
|
||||
};
|
||||
|
||||
pub fn intWidth(width: IntWidth) anytype {
|
||||
switch (width) {
|
||||
IntWidth.U8 => {
|
||||
return u8;
|
||||
},
|
||||
IntWidth.U16 => {
|
||||
return u16;
|
||||
},
|
||||
IntWidth.U32 => {
|
||||
return u32;
|
||||
},
|
||||
IntWidth.U64 => {
|
||||
return u64;
|
||||
},
|
||||
IntWidth.U128 => {
|
||||
return u128;
|
||||
},
|
||||
IntWidth.I8 => {
|
||||
return i8;
|
||||
},
|
||||
IntWidth.I16 => {
|
||||
return i16;
|
||||
},
|
||||
IntWidth.I32 => {
|
||||
return i32;
|
||||
},
|
||||
IntWidth.I64 => {
|
||||
return i64;
|
||||
},
|
||||
IntWidth.I128 => {
|
||||
return i128;
|
||||
},
|
||||
IntWidth.Usize => {
|
||||
return usize;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decref(
|
||||
bytes_or_null: ?[*]u8,
|
||||
data_bytes: usize,
|
||||
|
|
|
@ -9,6 +9,20 @@ use std::str;
|
|||
|
||||
fn main() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let dest_obj_path = Path::new(&out_dir).join("builtins.o");
|
||||
let dest_obj = dest_obj_path.to_str().expect("Invalid dest object path");
|
||||
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
println!("cargo:rustc-env=BUILTINS_O={}", dest_obj);
|
||||
|
||||
// When we build on Netlify, zig is not installed (but also not used,
|
||||
// since all we're doing is generating docs), so we can skip the steps
|
||||
// that require having zig installed.
|
||||
if env::var_os("NO_ZIG_INSTALLED").is_some() {
|
||||
// We still need to do the other things before this point, because
|
||||
// setting the env vars is needed for other parts of the build.
|
||||
return;
|
||||
}
|
||||
|
||||
let big_sur_path = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib";
|
||||
let use_build_script = Path::new(big_sur_path).exists();
|
||||
|
@ -34,8 +48,6 @@ fn main() {
|
|||
run_command(&bitcode_path, "zig", &["build", "ir", "-Drelease=true"]);
|
||||
}
|
||||
|
||||
let dest_obj_path = Path::new(&out_dir).join("builtins.o");
|
||||
let dest_obj = dest_obj_path.to_str().expect("Invalid dest object path");
|
||||
println!("Moving zig object to: {}", dest_obj);
|
||||
|
||||
run_command(&bitcode_path, "mv", &[src_obj, dest_obj]);
|
||||
|
@ -50,8 +62,6 @@ fn main() {
|
|||
&[dest_ir, "-o", dest_bc],
|
||||
);
|
||||
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
println!("cargo:rustc-env=BUILTINS_O={}", dest_obj);
|
||||
get_zig_files(bitcode_path.as_path(), &|path| {
|
||||
let path: &Path = path;
|
||||
println!(
|
||||
|
|
|
@ -55,12 +55,14 @@ and : Bool, Bool -> Bool
|
|||
##
|
||||
## In some languages, `&&` and `||` are special-cased in the compiler to skip
|
||||
## evaluating the expression after the operator under certain circumstances.
|
||||
## # In Roc, this is not the case. See the performance notes for #Bool.and for details.
|
||||
## # In Roc, this is not the case. See the performance notes for [Bool.and] for details.
|
||||
or : Bool, Bool -> Bool
|
||||
|
||||
## Exclusive or
|
||||
xor : Bool, Bool -> Bool
|
||||
|
||||
# TODO: removed `'` from signature because parser does not support it yet
|
||||
# Original signature: `isEq : 'val, 'val -> Bool`
|
||||
## Returns `True` if the two values are *structurally equal*, and `False` otherwise.
|
||||
##
|
||||
## `a == b` is shorthand for `Bool.isEq a b`
|
||||
|
@ -71,20 +73,18 @@ xor : Bool, Bool -> Bool
|
|||
## 2. Private tags are equal if they are the same tag, in the same module, and also their contents (if any) are equal.
|
||||
## 3. Records are equal if all their fields are equal.
|
||||
## 4. Collections ([Str], [List], [Dict], and [Set]) are equal if they are the same length, and also all their corresponding elements are equal.
|
||||
## 5. #Num values are equal if their numbers are equal, with one exception: if both arguments to `isEq` are *NaN*, then `isEq` returns `False`. See [Num.isNaN] for more about *NaN*.
|
||||
## 5. [Num] values are equal if their numbers are equal, with one exception: if both arguments to `isEq` are *NaN*, then `isEq` returns `False`. See [Num.isNaN] for more about *NaN*.
|
||||
##
|
||||
## Note that `isEq` takes `'val` instead of `val`, which means `isEq` does not
|
||||
## accept arguments whose types contain functions.
|
||||
# TODO: removed `'` from signature because parser does not support it yet
|
||||
# Original signature: `isEq : 'val, 'val -> Bool`
|
||||
isEq : val, val -> Bool
|
||||
|
||||
## Calls #eq on the given values, then calls #not on the result.
|
||||
# TODO: removed `'` from signature because parser does not support it yet
|
||||
# Original signature: `isNotEq : 'val, 'val -> Bool`
|
||||
## Calls [isEq] on the given values, then calls [not] on the result.
|
||||
##
|
||||
## `a != b` is shorthand for `Bool.isNotEq a b`
|
||||
##
|
||||
## Note that `isNotEq` takes `'val` instead of `val`, which means `isNotEq` does not
|
||||
## accept arguments whose types contain functions.
|
||||
# TODO: removed `'` from signature because parser does not support it yet
|
||||
# Original signature: `isNotEq : 'val, 'val -> Bool`
|
||||
isNotEq : val, val -> Bool
|
||||
|
|
|
@ -3,12 +3,6 @@ pub const OBJ_PATH: &str = env!(
|
|||
"Env var BUILTINS_O not found. Is there a problem with the build script?"
|
||||
);
|
||||
|
||||
pub fn as_bytes() -> &'static [u8] {
|
||||
// In the build script for the builtins module,
|
||||
// we compile the builtins into LLVM bitcode
|
||||
include_bytes!("../bitcode/builtins.bc")
|
||||
}
|
||||
|
||||
pub const NUM_ASIN: &str = "roc_builtins.num.asin";
|
||||
pub const NUM_ACOS: &str = "roc_builtins.num.acos";
|
||||
pub const NUM_ATAN: &str = "roc_builtins.num.atan";
|
||||
|
|
|
@ -49,7 +49,8 @@ use roc_module::ident::TagName;
|
|||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||
use roc_mono::ir::{
|
||||
BranchInfo, CallType, ExceptionId, JoinPointId, ModifyRc, TopLevelFunctionLayout, Wrapped,
|
||||
BranchInfo, CallType, ExceptionId, JoinPointId, ModifyRc, OptLevel, TopLevelFunctionLayout,
|
||||
Wrapped,
|
||||
};
|
||||
use roc_mono::layout::{Builtin, InPlace, LambdaSet, Layout, LayoutIds, UnionLayout};
|
||||
use target_lexicon::CallingConvention;
|
||||
|
@ -86,21 +87,6 @@ macro_rules! debug_info_init {
|
|||
}};
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum OptLevel {
|
||||
Normal,
|
||||
Optimize,
|
||||
}
|
||||
|
||||
impl From<OptLevel> for OptimizationLevel {
|
||||
fn from(level: OptLevel) -> Self {
|
||||
match level {
|
||||
OptLevel::Normal => OptimizationLevel::None,
|
||||
OptLevel::Optimize => OptimizationLevel::Aggressive,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate over all functions in an llvm module
|
||||
pub struct FunctionIterator<'ctx> {
|
||||
next: Option<FunctionValue<'ctx>>,
|
||||
|
@ -355,7 +341,9 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
|
|||
}
|
||||
|
||||
pub fn module_from_builtins<'ctx>(ctx: &'ctx Context, module_name: &str) -> Module<'ctx> {
|
||||
let bitcode_bytes = bitcode::as_bytes();
|
||||
// In the build script for the builtins module,
|
||||
// we compile the builtins into LLVM bitcode
|
||||
let bitcode_bytes: &[u8] = include_bytes!("../../../builtins/bitcode/builtins.bc");
|
||||
|
||||
let memory_buffer = MemoryBuffer::create_from_memory_range(&bitcode_bytes, module_name);
|
||||
|
||||
|
|
|
@ -43,6 +43,12 @@ macro_rules! return_on_layout_error {
|
|||
};
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum OptLevel {
|
||||
Normal,
|
||||
Optimize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum MonoProblem {
|
||||
PatternProblem(crate::exhaustive::Error),
|
||||
|
|
|
@ -6,6 +6,7 @@ use roc_can::def::Def;
|
|||
use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_gen::llvm::externs::add_default_roc_externs;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_mono::ir::OptLevel;
|
||||
use roc_types::subs::VarStore;
|
||||
|
||||
fn promote_expr_to_module(src: &str) -> String {
|
||||
|
@ -190,9 +191,9 @@ pub fn helper<'a>(
|
|||
module.strip_debug_info();
|
||||
|
||||
let opt_level = if cfg!(debug_assertions) {
|
||||
roc_gen::llvm::build::OptLevel::Normal
|
||||
OptLevel::Normal
|
||||
} else {
|
||||
roc_gen::llvm::build::OptLevel::Optimize
|
||||
OptLevel::Optimize
|
||||
};
|
||||
|
||||
let module = arena.alloc(module);
|
||||
|
|
|
@ -63,9 +63,10 @@ pub fn generate(filenames: Vec<PathBuf>, std_lib: StdLib, build_dir: &Path) {
|
|||
// Write each package's module docs html file
|
||||
for (docs_by_id, interns) in package.modules.iter_mut() {
|
||||
for module in docs_by_id.values_mut() {
|
||||
let mut filename = String::new();
|
||||
filename.push_str(module.name.as_str());
|
||||
filename.push_str(".html");
|
||||
let module_dir = build_dir.join(module.name.as_str());
|
||||
|
||||
fs::create_dir(&module_dir)
|
||||
.expect("TODO gracefully handle not being able to create the module dir");
|
||||
|
||||
let rendered_module = template_html
|
||||
.replace(
|
||||
|
@ -78,7 +79,7 @@ pub fn generate(filenames: Vec<PathBuf>, std_lib: StdLib, build_dir: &Path) {
|
|||
render_main_content(interns, module).as_str(),
|
||||
);
|
||||
|
||||
fs::write(build_dir.join(filename), rendered_module)
|
||||
fs::write(module_dir.join("index.html"), rendered_module)
|
||||
.expect("TODO gracefully handle failing to write html");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
{ pkgs }:
|
||||
|
||||
let
|
||||
# system helpers
|
||||
splitSystem = builtins.split "-" builtins.currentSystem;
|
||||
arch = builtins.elemAt splitSystem 0;
|
||||
isAarch64 = arch == "aarch64";
|
||||
setForSystem = { darwin, darwinAarch64, linux, linuxAarch64 }:
|
||||
if pkgs.stdenv.isDarwin
|
||||
then (
|
||||
if isAarch64
|
||||
then darwinAarch64
|
||||
else darwin
|
||||
)
|
||||
else (
|
||||
if isAarch64
|
||||
then linuxAarch64
|
||||
else linux
|
||||
);
|
||||
|
||||
version = "0.8.0-dev.2711+11ae6c42c";
|
||||
osName =
|
||||
if pkgs.stdenv.isDarwin
|
||||
then "macos" else "linux";
|
||||
archiveName = "zig-${osName}-${arch}-${version}";
|
||||
sha256 = setForSystem {
|
||||
darwin = "bf2a4cd1516d202cfbbcaa7b1308d36aa21a9f9284b39297e70f98c003f479e3";
|
||||
darwinAarch64 = "6bc35c3b40b853cd351c890c94c4a6043f5ca492ff6d704bdb1544fe1fe54d9a";
|
||||
linux = "b443cc2259fe7712ffc954745266e3ec846e27854713d817bcec35fefd655a8c";
|
||||
linuxAarch64 = "229830e6dc92f641a1106af3a8ee96fdef379ffd3a3d7db7ed62d2b46bd8ed45";
|
||||
};
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
pname = "zig-unstable";
|
||||
version = version;
|
||||
src = pkgs.fetchurl {
|
||||
inherit sha256;
|
||||
name = "${archiveName}.tar.xz";
|
||||
url = "https://ziglang.org/builds/${archiveName}.tar.xz";
|
||||
};
|
||||
phases = [ "unpackPhase" ];
|
||||
unpackPhase = ''
|
||||
mkdir -p $out/bin
|
||||
tar -xf $src
|
||||
cp ${archiveName}/zig $out/zig
|
||||
cp -r ${archiveName}/lib $out/lib
|
||||
ln -s "$out/zig" "$out/bin/zig"
|
||||
chmod +x $out/bin/zig
|
||||
'';
|
||||
}
|
32
nix/zig.nix
32
nix/zig.nix
|
@ -1,10 +1,32 @@
|
|||
{ pkgs }:
|
||||
|
||||
if pkgs.stdenv.isDarwin then
|
||||
let
|
||||
version = "0.7.1";
|
||||
archiveName = "zig-macos-x86_64-${version}";
|
||||
sha256 = "845cb17562978af0cf67e3993f4e33330525eaf01ead9386df9105111e3bc519";
|
||||
version = "0.8.0";
|
||||
|
||||
osName =
|
||||
if pkgs.stdenv.isDarwin then
|
||||
"macos"
|
||||
else
|
||||
"linux";
|
||||
|
||||
splitSystem = builtins.split "-" builtins.currentSystem;
|
||||
arch = builtins.elemAt splitSystem 0;
|
||||
isAarch64 = arch == "aarch64";
|
||||
|
||||
archiveName = "zig-${osName}-${arch}-${version}";
|
||||
|
||||
# If you're system is not aarch64, we assume it's x86_64
|
||||
sha256 =
|
||||
if pkgs.stdenv.isDarwin then
|
||||
if isAarch64 then
|
||||
"b32d13f66d0e1ff740b3326d66a469ee6baddbd7211fa111c066d3bd57683111"
|
||||
else
|
||||
"279f9360b5cb23103f0395dc4d3d0d30626e699b1b4be55e98fd985b62bc6fbe"
|
||||
else
|
||||
if isAarch64 then
|
||||
"ee204ca2c2037952cf3f8b10c609373a08a291efa4af7b3c73be0f2b27720470"
|
||||
else
|
||||
"502625d3da3ae595c5f44a809a87714320b7a40e6dff4a895b5fa7df3391d01e";
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
pname = "zig";
|
||||
|
@ -24,5 +46,3 @@ if pkgs.stdenv.isDarwin then
|
|||
chmod +x $out/bin/zig
|
||||
'';
|
||||
}
|
||||
else
|
||||
pkgs.zig
|
||||
|
|
|
@ -44,7 +44,6 @@ let
|
|||
|
||||
llvmPkgs = pkgs.llvmPackages_10;
|
||||
|
||||
# zig = import ./nix/zig-unstable.nix { inherit pkgs; };
|
||||
zig = import ./nix/zig.nix { inherit pkgs; };
|
||||
|
||||
inputs = with pkgs;[
|
||||
|
|
1
www/.gitignore
vendored
Normal file
1
www/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
build
|
20
www/build.sh
Executable file
20
www/build.sh
Executable file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
# cd into the directory where this script lives.
|
||||
# This allows us to run this script from the root project directory,
|
||||
# which is what Netlify wants to do.
|
||||
SCRIPT_RELATIVE_DIR=$(dirname "${BASH_SOURCE[0]}")
|
||||
cd $SCRIPT_RELATIVE_DIR
|
||||
|
||||
rm -rf build/
|
||||
cp -r public/ build/
|
||||
|
||||
pushd ..
|
||||
echo 'Generating docs...'
|
||||
# We run the CLI with --no-default-features because that way we don't have a LLVM
|
||||
# dependency. (Netlify's build servers have Rust installed, but not LLVM.)
|
||||
cargo run -p roc_cli --no-default-features docs compiler/builtins/docs/Bool.roc
|
||||
mv generated-docs/ www/build/builtins
|
||||
popd
|
30
www/netlify.toml
Normal file
30
www/netlify.toml
Normal file
|
@ -0,0 +1,30 @@
|
|||
# This is the file that generates and deploys https://www.roc-lang.org,
|
||||
# which is served on Netlify.
|
||||
#
|
||||
# Netlify's docs for how this configuration file works:
|
||||
# https://docs.netlify.com/routing/headers/#syntax-for-the-netlify-configuration-file
|
||||
[build]
|
||||
publish = "build/"
|
||||
command = "bash build.sh"
|
||||
|
||||
[[headers]]
|
||||
for = "/*"
|
||||
[headers.values]
|
||||
X-Frame-Options = "DENY"
|
||||
X-XSS-Protection = "1; mode=block"
|
||||
Content-Security-Policy = "default-src 'self'; img-src *;"
|
||||
X-Content-Type-Options = "nosniff"
|
||||
|
||||
# Redirect roc-lang.org/authors to the AUTHORS file in this repo
|
||||
#
|
||||
# This is referenced in the LICENSE file, which says to see roc-lang.org/authors
|
||||
# for a list of authors!
|
||||
[[redirects]]
|
||||
from = "/authors"
|
||||
to = "https://github.com/rtfeldman/roc/blob/trunk/AUTHORS"
|
||||
force = true
|
||||
status = 302 # TODO once the repo is public, use status = 200 and this URL:
|
||||
# https://raw.githubusercontent.com/rtfeldman/roc/trunk/AUTHORS
|
||||
#
|
||||
# This way, roc-lang.org/authors will show the authors directly,
|
||||
# proxied from the current AUTHORS file on GitHub, no redirects.
|
4
www/public/favicon.svg
Normal file
4
www/public/favicon.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg viewBox="0 0 52 53" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>polygon {fill: #5c0bff;}@media (prefers-color-scheme: dark) {polygon {fill: #7733ff;}} </style>
|
||||
<polygon points="0,0 23.8834,3.21052 37.2438,19.0101 45.9665,16.6324 50.5,22 45,22 44.0315,26.3689 26.4673,39.3424 27.4527,45.2132 17.655,53 23.6751,22.7086"/>
|
||||
</svg>
|
After Width: | Height: | Size: 335 B |
23
www/public/index.html
Normal file
23
www/public/index.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!doctype html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>The Roc Programming Language</title>
|
||||
<!-- <meta name="description" content="A language for making delightful software."> -->
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<!-- <link rel="icon" href="/favicon.svg"> -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Work in Progress</h1>
|
||||
<p>Roc's initial release is still under development, and this website is a placeholder until that release is ready.</p>
|
||||
<p>In the meantime, if you'd like to learn more about Roc, here are some videos:</p>
|
||||
<ul>
|
||||
<li><a href="https://youtu.be/FMyyYdFSOHA">Roc on Zig Showtime</a> - April 24, 2021</li>
|
||||
<li><a href="https://youtu.be/ZnYa99QoznE?t=4790">Roc at the Berlin FP Meetup</a> - September 1, 2020 (this one has details on how to try out Roc or get involved)</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
29
www/public/license/index.html
Normal file
29
www/public/license/index.html
Normal file
|
@ -0,0 +1,29 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Roc's license: The Universal Permissive License (UPL), Version 1.0</title>
|
||||
<meta name="description" content="The software license for the code in the Roc programming language.">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<link rel="icon" href="/favicon.svg">
|
||||
</head>
|
||||
<body><pre><code>Copyright (c) 2019 Richard Feldman and subsequent Roc authors <<a href="https://roc-lang.org/authors">https://roc-lang.org/authors</a>>
|
||||
|
||||
<a href="https://opensource.org/licenses/UPL">The Universal Permissive License (UPL), Version 1.0</a>
|
||||
|
||||
Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this software, associated documentation and/or data (collectively the "Software"), free of charge and under any and all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or (ii) the Larger Works (as defined below), to deal in both
|
||||
|
||||
(a) the Software, and
|
||||
|
||||
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software (each a “Larger Work” to which the Software is contributed by such licensors),
|
||||
|
||||
without restriction, including without limitation the rights to copy, create derivative works of, display, perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms.
|
||||
|
||||
This license is subject to the following condition:
|
||||
|
||||
The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</body></code></pre>
|
||||
</html>
|
9
www/public/logo.svg
Normal file
9
www/public/logo.svg
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="240" height="240" viewBox="0 0 51 53" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M23.6751 22.7086L17.655 53L27.4527 45.2132L26.4673 39.3424L23.6751 22.7086Z" fill="#612BDE"/>
|
||||
<path d="M37.2438 19.0101L44.0315 26.3689L45 22L45.9665 16.6324L37.2438 19.0101Z" fill="#8257E5"/>
|
||||
<path d="M23.8834 3.21052L0 0L23.6751 22.7086L23.8834 3.21052Z" fill="#8257E5"/>
|
||||
<path d="M44.0315 26.3689L23.6751 22.7086L26.4673 39.3424L44.0315 26.3689Z" fill="#8257E5"/>
|
||||
<path d="M50.5 22L45.9665 16.6324L45 22H50.5Z" fill="#612BDE"/>
|
||||
<path d="M23.6751 22.7086L44.0315 26.3689L37.2438 19.0101L23.8834 3.21052L23.6751 22.7086Z" fill="#612BDE"/>
|
||||
</svg>
|
After Width: | Height: | Size: 705 B |
38
www/public/search.js
Normal file
38
www/public/search.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
(function() {
|
||||
let sidebar = document.getElementById("sidebar-nav");
|
||||
let searchBox = document.getElementById("module-search");
|
||||
|
||||
function search() {
|
||||
let text = searchBox.value.toLowerCase(); // Search is case-insensitive.
|
||||
|
||||
if (text === "") {
|
||||
// Un-hide everything
|
||||
sidebar.querySelectorAll(".sidebar-entry a").forEach((entry) => entry.classList.remove("hidden"));
|
||||
|
||||
// Re-hide all the sub-entries except for those of the first module
|
||||
sidebar.querySelectorAll(".sidebar-entry:not(:first-of-type) .sidebar-sub-entries a").forEach((entry) => entry.classList.add("hidden"));
|
||||
} else {
|
||||
// First, show/hide all the sub-entries within each module (top-level functions etc.)
|
||||
sidebar.querySelectorAll(".sidebar-sub-entries a").forEach((entry) => {
|
||||
if (entry.textContent.toLowerCase().includes(text)) {
|
||||
entry.classList.remove("hidden");
|
||||
} else {
|
||||
entry.classList.add("hidden");
|
||||
}
|
||||
});
|
||||
|
||||
// Then, show/hide modules based on whether they match, or any of their sub-entries matched
|
||||
sidebar.querySelectorAll(".sidebar-module-link").forEach((entry) => {
|
||||
if (entry.textContent.toLowerCase().includes(text) || entry.parentNode.querySelectorAll(".sidebar-sub-entries a:not(.hidden)").length > 0) {
|
||||
entry.classList.remove("hidden");
|
||||
} else {
|
||||
entry.classList.add("hidden");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
searchBox.addEventListener("input", search);
|
||||
|
||||
search();
|
||||
})();
|
479
www/public/styles.css
Normal file
479
www/public/styles.css
Normal file
|
@ -0,0 +1,479 @@
|
|||
:root {
|
||||
--link-color: #612bde;
|
||||
--code-link-color: #5721d4;
|
||||
--text-color: #333333;
|
||||
--code-color: #222222;
|
||||
--code-bg-color: #eeeeee;
|
||||
--body-bg-color: #fdfdfd;
|
||||
--border-color: #e9e9e9;
|
||||
--faded-color: #4c4c4c;
|
||||
--monospace-font;
|
||||
--font-sans: -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
|
||||
--font-mono: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
--top-header-height: 67px;
|
||||
--sidebar-width: 280px;
|
||||
--top-bar-bg: #8257e5;
|
||||
--top-bar-fg: #ffffff;
|
||||
--nav-link-hover-color: #000000;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #972395;
|
||||
}
|
||||
|
||||
.logo {
|
||||
padding: 2px 8px;
|
||||
}
|
||||
|
||||
.logo svg {
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
fill: var(--top-bar-fg);
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.logo svg:hover {
|
||||
fill: var(--nav-link-hover-color);
|
||||
}
|
||||
|
||||
.pkg-full-name {
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 32px;
|
||||
margin: 0 8px;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.pkg-full-name a {
|
||||
padding-top: 12px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.pkg-and-logo {
|
||||
min-width: 0; /* necessary for text-overflow: ellipsis to work in descendants */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
background-color: var(--top-bar-bg);
|
||||
}
|
||||
|
||||
.pkg-and-logo a, .pkg-and-logo a:visited {
|
||||
color: var(--top-bar-fg);
|
||||
}
|
||||
|
||||
.pkg-and-logo a:hover {
|
||||
color: var(--nav-link-hover-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.main-container {
|
||||
min-width: 0; /* necessary for text-overflow: ellipsis to work in descendants */
|
||||
}
|
||||
|
||||
.search-button {
|
||||
flex-shrink: 0; /* always shrink the package name before these; they have a relatively constrained length */
|
||||
padding: 12px 18px;
|
||||
margin-right: 42px;
|
||||
display: none; /* only show this in the mobile view */
|
||||
}
|
||||
|
||||
.version {
|
||||
padding: 18px 10px;
|
||||
min-width: 48px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
body {
|
||||
display: grid;
|
||||
grid-template-columns: [before-sidebar] 1fr [sidebar] var(--sidebar-width) [main-content] fit-content(calc(1280px - var(--sidebar-width))) [end] 1fr;
|
||||
grid-template-rows: [top-header] var(--top-header-height) [above-footer] auto [footer] auto;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: var(--font-sans);
|
||||
color: var(--text-color);
|
||||
background-color: var(--body-bg-color);
|
||||
}
|
||||
|
||||
main {
|
||||
grid-column-start: main-content;
|
||||
grid-column-end: main-content;
|
||||
grid-row-start: above-footer;
|
||||
grid-row-end: above-footer;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
font-size: 18px;
|
||||
line-height: 1.85em;
|
||||
margin-top: 2px;
|
||||
padding: 48px;
|
||||
}
|
||||
|
||||
#sidebar-nav {
|
||||
grid-column-start: sidebar;
|
||||
grid-column-end: sidebar;
|
||||
grid-row-start: above-footer;
|
||||
grid-row-end: above-footer;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
padding-left: 56px;
|
||||
padding-top: 6px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.top-header-extension {
|
||||
grid-column-start: before-sidebar;
|
||||
grid-column-end: sidebar;
|
||||
grid-row-start: top-header;
|
||||
grid-row-end: top-header;
|
||||
background-color: var(--top-bar-bg);
|
||||
}
|
||||
|
||||
.top-header {
|
||||
grid-column-start: sidebar;
|
||||
grid-column-end: end;
|
||||
grid-row-start: top-header;
|
||||
grid-row-end: top-header;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
flex-grow: 1;
|
||||
box-sizing: border-box;
|
||||
font-family: var(--font-sans);
|
||||
font-size: 24px;
|
||||
height: 100%;
|
||||
min-width: 0; /* necessary for text-overflow: ellipsis to work in descendants */
|
||||
}
|
||||
|
||||
.top-header-triangle {
|
||||
/* This used to be a clip-path, but Firefox on Android (at least as of early 2020)
|
||||
* rendered the page extremely slowly in that version. With this approach it's super fast.
|
||||
*/
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: var(--top-header-height) 0 0 48px;
|
||||
border-color: transparent transparent transparent var(--top-bar-bg);
|
||||
}
|
||||
|
||||
p {
|
||||
overflow-wrap: break-word;
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
footer {
|
||||
grid-column-start: main-content;
|
||||
grid-column-end: main-content;
|
||||
grid-row-start: footer;
|
||||
grid-row-end: footer;
|
||||
max-width: var(--main-content-max-width);
|
||||
font-size: 14px;
|
||||
box-sizing: border-box;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
footer p {
|
||||
display: inline-block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.sidebar-entry ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar-entry a {
|
||||
box-sizing: border-box;
|
||||
min-height: 48px;
|
||||
min-width: 48px;
|
||||
padding: 12px 16px;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.sidebar-sub-entries a {
|
||||
display: block;
|
||||
line-height: 24px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding-left: 36px;
|
||||
}
|
||||
|
||||
.module-name {
|
||||
font-size: 56px;
|
||||
line-height: 1em;
|
||||
font-family: var(--font-mono);
|
||||
font-weight: bold;
|
||||
margin-top: 18px;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
|
||||
.module-name a, .module-name a:visited {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.sidebar-module-link {
|
||||
box-sizing: border-box;
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
font-family: var(--font-mono);
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 8px 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
a, a:visited {
|
||||
color: var(--link-color);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 32px;
|
||||
margin: 48px 0 24px 0;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.type-def {
|
||||
font-size: 24px;
|
||||
color: var(--link-color);
|
||||
}
|
||||
|
||||
.code-snippet {
|
||||
padding: 12px 16px;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
font-family: var(--font-mono);
|
||||
background-color: var(--code-bg-color);
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
color: var(--code-color);
|
||||
background-color: var(--code-bg-color);
|
||||
padding: 2px 8px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
code a {
|
||||
color: var(--code-link-color);
|
||||
}
|
||||
|
||||
code a:visited {
|
||||
color: var(--code-link-color);
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 36px 0;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--code-bg-color);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
pre code {
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
/* Use !important to win all specificity fights. */
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#module-search:placeholder-shown {
|
||||
padding: 0;
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
#module-search, #module-search:focus {
|
||||
opacity: 1;
|
||||
padding: 12px 16px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
/* Show the "Search" label link when the text input has a placeholder */
|
||||
#module-search:placeholder-shown + #search-link {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* Hide the "Search" label link when the text input has focus */
|
||||
#module-search:focus + #search-link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#module-search {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--code-bg-color);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
font-size: 18px;
|
||||
line-height: 18px;
|
||||
margin-top: 6px;
|
||||
border: none;
|
||||
color: var(--faded-color);
|
||||
background-color: var(--code-bg-color);
|
||||
font-family: var(--font-serif);
|
||||
}
|
||||
|
||||
#module-search::placeholder {
|
||||
color: var(--faded-color);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#search-link {
|
||||
box-sizing: border-box;
|
||||
display: none;
|
||||
align-items: center;
|
||||
font-size: 18px;
|
||||
line-height: 18px;
|
||||
padding: 12px 16px;
|
||||
height: 48px;
|
||||
cursor: pointer;
|
||||
color: var(--link-color);
|
||||
}
|
||||
|
||||
#search-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--body-bg-color: #303030;
|
||||
--code-bg-color: #393939;
|
||||
--border-color: #555555;
|
||||
--code-color: #eeeeee;
|
||||
--text-color: #cccccc;
|
||||
--logo-solid: #777777;
|
||||
--faded-color: #bbbbbb;
|
||||
--link-color: #c5a8ff;
|
||||
--code-link-color: #b894ff;
|
||||
--top-bar-bg: #6845b9;
|
||||
--top-bar-fg: #eeeeee;
|
||||
}
|
||||
|
||||
html {
|
||||
scrollbar-color: #444444 #2f2f2f;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-device-width: 480px) {
|
||||
.search-button {
|
||||
display: block; /* This is only visible in mobile. */
|
||||
}
|
||||
|
||||
.top-header {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.pkg-full-name {
|
||||
margin-left: 8px;
|
||||
margin-right: 12px;
|
||||
font-size: 24px;
|
||||
padding-bottom: 14px;
|
||||
}
|
||||
|
||||
.pkg-full-name a {
|
||||
vertical-align: middle;
|
||||
padding: 18px 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
padding-left: 2px;
|
||||
width: 50px;
|
||||
height: 54px;
|
||||
}
|
||||
|
||||
.version {
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
font-size: 18px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.module-name {
|
||||
font-size: 36px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
max-width: calc(100% - 18px);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 18px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 0;
|
||||
min-width: 320px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
margin-top: 0;
|
||||
padding-left: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
#sidebar-heading {
|
||||
font-size: 24px;
|
||||
margin: 16px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.top-header {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.content {
|
||||
/* Display the sidebar below <main> without affecting tab index */
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue