mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Several migration fixes and make some zig parser improvements based on migrated code in the wild (#7716)
This commit is contained in:
parent
68af4b9a06
commit
6d22c4dd7c
329 changed files with 1663 additions and 833 deletions
|
@ -9,6 +9,7 @@ use roc_can::expr::{DeclarationTag, Declarations, Expr};
|
||||||
use roc_error_macros::{internal_error, user_error};
|
use roc_error_macros::{internal_error, user_error};
|
||||||
use roc_fmt::def::fmt_defs;
|
use roc_fmt::def::fmt_defs;
|
||||||
use roc_fmt::header::fmt_header;
|
use roc_fmt::header::fmt_header;
|
||||||
|
use roc_fmt::migrate::MigrateError;
|
||||||
use roc_fmt::Buf;
|
use roc_fmt::Buf;
|
||||||
use roc_fmt::MigrationFlags;
|
use roc_fmt::MigrationFlags;
|
||||||
use roc_load::{ExecutionMode, FunctionKind, LoadConfig, LoadedModule, LoadingProblem, Threading};
|
use roc_load::{ExecutionMode, FunctionKind, LoadConfig, LoadedModule, LoadingProblem, Threading};
|
||||||
|
@ -78,7 +79,7 @@ fn is_roc_file(path: &Path) -> bool {
|
||||||
pub fn format_files(
|
pub fn format_files(
|
||||||
files: std::vec::Vec<PathBuf>,
|
files: std::vec::Vec<PathBuf>,
|
||||||
mode: FormatMode,
|
mode: FormatMode,
|
||||||
flags: MigrationFlags,
|
migrate: bool,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let arena = Bump::new();
|
let arena = Bump::new();
|
||||||
let mut files_to_reformat = Vec::new(); // to track which files failed `roc format --check`
|
let mut files_to_reformat = Vec::new(); // to track which files failed `roc format --check`
|
||||||
|
@ -86,7 +87,7 @@ pub fn format_files(
|
||||||
for file in flatten_directories(files) {
|
for file in flatten_directories(files) {
|
||||||
let src = std::fs::read_to_string(&file).unwrap();
|
let src = std::fs::read_to_string(&file).unwrap();
|
||||||
|
|
||||||
match format_src(&arena, &src, flags) {
|
match format_src(&arena, &src, migrate) {
|
||||||
Ok(buf) => {
|
Ok(buf) => {
|
||||||
match mode {
|
match mode {
|
||||||
FormatMode::CheckOnly => {
|
FormatMode::CheckOnly => {
|
||||||
|
@ -168,6 +169,11 @@ pub fn format_files(
|
||||||
unstable_2_file.display()
|
unstable_2_file.display()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
FormatProblem::UnsupportedMigration(e) => internal_error!(
|
||||||
|
"Formatting bug; unsupported migration\n\n\
|
||||||
|
Migration error was: {:?}\n\n",
|
||||||
|
e
|
||||||
|
),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,13 +203,28 @@ pub enum FormatProblem {
|
||||||
formatted_src: String,
|
formatted_src: String,
|
||||||
reformatted_src: String,
|
reformatted_src: String,
|
||||||
},
|
},
|
||||||
|
UnsupportedMigration(MigrateError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format_src(arena: &Bump, src: &str, flags: MigrationFlags) -> Result<String, FormatProblem> {
|
pub fn format_src(arena: &Bump, src: &str, migrate: bool) -> Result<String, FormatProblem> {
|
||||||
let ast = arena.alloc(parse_all(arena, src).unwrap_or_else(|e| {
|
let ast = arena.alloc(parse_all(arena, src).unwrap_or_else(|e| {
|
||||||
user_error!("Unexpected parse failure when parsing this formatting:\n\n{src}\n\nParse error was:\n\n{:#?}\n\n", e)
|
user_error!("Unexpected parse failure when parsing this formatting:\n\n{src}\n\nParse error was:\n\n{:#?}\n\n", e)
|
||||||
}));
|
}));
|
||||||
|
let flags = MigrationFlags {
|
||||||
|
snakify: migrate,
|
||||||
|
parens_and_commas: migrate,
|
||||||
|
};
|
||||||
let mut buf = Buf::new_in(arena, flags);
|
let mut buf = Buf::new_in(arena, flags);
|
||||||
|
|
||||||
|
if migrate {
|
||||||
|
roc_fmt::migrate::fmt_header(&mut buf, &ast.header)
|
||||||
|
.map_err(FormatProblem::UnsupportedMigration)?;
|
||||||
|
roc_fmt::migrate::fmt_defs(&mut buf, &ast.defs)
|
||||||
|
.map_err(FormatProblem::UnsupportedMigration)?;
|
||||||
|
buf.fmt_end_of_file();
|
||||||
|
return Ok(buf.as_str().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
fmt_all(&mut buf, ast);
|
fmt_all(&mut buf, ast);
|
||||||
|
|
||||||
let reparsed_ast = match arena.alloc(parse_all(arena, buf.as_str())) {
|
let reparsed_ast = match arena.alloc(parse_all(arena, buf.as_str())) {
|
||||||
|
@ -224,9 +245,7 @@ pub fn format_src(arena: &Bump, src: &str, flags: MigrationFlags) -> Result<Stri
|
||||||
// the PartialEq implementation is returning `false` even when the Debug-formatted impl is exactly the same.
|
// the PartialEq implementation is returning `false` even when the Debug-formatted impl is exactly the same.
|
||||||
// I don't have the patience to debug this right now, so let's leave it for another day...
|
// I don't have the patience to debug this right now, so let's leave it for another day...
|
||||||
// TODO: fix PartialEq impl on ast types
|
// TODO: fix PartialEq impl on ast types
|
||||||
if !flags.at_least_one_active()
|
if format!("{ast_normalized:?}") != format!("{reparsed_ast_normalized:?}") {
|
||||||
&& format!("{ast_normalized:?}") != format!("{reparsed_ast_normalized:?}")
|
|
||||||
{
|
|
||||||
return Err(FormatProblem::ReformattingChangedAst {
|
return Err(FormatProblem::ReformattingChangedAst {
|
||||||
formatted_src: buf.as_str().to_string(),
|
formatted_src: buf.as_str().to_string(),
|
||||||
ast_before: format!("{ast_normalized:#?}\n"),
|
ast_before: format!("{ast_normalized:#?}\n"),
|
||||||
|
@ -235,7 +254,7 @@ pub fn format_src(arena: &Bump, src: &str, flags: MigrationFlags) -> Result<Stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now verify that the resultant formatting is _stable_ - i.e. that it doesn't change again if re-formatted
|
// Now verify that the resultant formatting is _stable_ - i.e. that it doesn't change again if re-formatted
|
||||||
let mut reformatted_buf = Buf::new_in(arena, flags);
|
let mut reformatted_buf = Buf::new_in(arena, MigrationFlags::default());
|
||||||
|
|
||||||
fmt_all(&mut reformatted_buf, reparsed_ast);
|
fmt_all(&mut reformatted_buf, reparsed_ast);
|
||||||
|
|
||||||
|
@ -483,12 +502,7 @@ main =
|
||||||
fn test_single_file_needs_reformatting() {
|
fn test_single_file_needs_reformatting() {
|
||||||
let dir = tempdir().unwrap();
|
let dir = tempdir().unwrap();
|
||||||
let file_path = setup_test_file(dir.path(), "test1.roc", UNFORMATTED_ROC);
|
let file_path = setup_test_file(dir.path(), "test1.roc", UNFORMATTED_ROC);
|
||||||
let flags = MigrationFlags {
|
let result = format_files(vec![file_path.clone()], FormatMode::CheckOnly, false);
|
||||||
snakify: false,
|
|
||||||
parens_and_commas: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = format_files(vec![file_path.clone()], FormatMode::CheckOnly, flags);
|
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.unwrap_err(),
|
result.unwrap_err(),
|
||||||
|
@ -506,12 +520,7 @@ main =
|
||||||
let dir = tempdir().unwrap();
|
let dir = tempdir().unwrap();
|
||||||
let file1 = setup_test_file(dir.path(), "test1.roc", UNFORMATTED_ROC);
|
let file1 = setup_test_file(dir.path(), "test1.roc", UNFORMATTED_ROC);
|
||||||
let file2 = setup_test_file(dir.path(), "test2.roc", UNFORMATTED_ROC);
|
let file2 = setup_test_file(dir.path(), "test2.roc", UNFORMATTED_ROC);
|
||||||
let flags = MigrationFlags {
|
let result = format_files(vec![file1, file2], FormatMode::CheckOnly, false);
|
||||||
snakify: false,
|
|
||||||
parens_and_commas: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = format_files(vec![file1, file2], FormatMode::CheckOnly, flags);
|
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
let error_message = result.unwrap_err();
|
let error_message = result.unwrap_err();
|
||||||
assert!(error_message.contains("test1.roc") && error_message.contains("test2.roc"));
|
assert!(error_message.contains("test1.roc") && error_message.contains("test2.roc"));
|
||||||
|
@ -523,12 +532,7 @@ main =
|
||||||
fn test_no_files_need_reformatting() {
|
fn test_no_files_need_reformatting() {
|
||||||
let dir = tempdir().unwrap();
|
let dir = tempdir().unwrap();
|
||||||
let file_path = setup_test_file(dir.path(), "formatted.roc", FORMATTED_ROC);
|
let file_path = setup_test_file(dir.path(), "formatted.roc", FORMATTED_ROC);
|
||||||
let flags = MigrationFlags {
|
let result = format_files(vec![file_path], FormatMode::CheckOnly, false);
|
||||||
snakify: false,
|
|
||||||
parens_and_commas: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = format_files(vec![file_path], FormatMode::CheckOnly, flags);
|
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
|
|
||||||
cleanup_temp_dir(dir);
|
cleanup_temp_dir(dir);
|
||||||
|
@ -540,15 +544,10 @@ main =
|
||||||
let file_formatted = setup_test_file(dir.path(), "formatted.roc", FORMATTED_ROC);
|
let file_formatted = setup_test_file(dir.path(), "formatted.roc", FORMATTED_ROC);
|
||||||
let file1_unformated = setup_test_file(dir.path(), "test1.roc", UNFORMATTED_ROC);
|
let file1_unformated = setup_test_file(dir.path(), "test1.roc", UNFORMATTED_ROC);
|
||||||
let file2_unformated = setup_test_file(dir.path(), "test2.roc", UNFORMATTED_ROC);
|
let file2_unformated = setup_test_file(dir.path(), "test2.roc", UNFORMATTED_ROC);
|
||||||
let flags = MigrationFlags {
|
|
||||||
snakify: false,
|
|
||||||
parens_and_commas: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = format_files(
|
let result = format_files(
|
||||||
vec![file_formatted, file1_unformated, file2_unformated],
|
vec![file_formatted, file1_unformated, file2_unformated],
|
||||||
FormatMode::CheckOnly,
|
FormatMode::CheckOnly,
|
||||||
flags,
|
false,
|
||||||
);
|
);
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
let error_message = result.unwrap_err();
|
let error_message = result.unwrap_err();
|
||||||
|
|
|
@ -13,7 +13,6 @@ use roc_cli::{
|
||||||
};
|
};
|
||||||
use roc_docs::generate_docs_html;
|
use roc_docs::generate_docs_html;
|
||||||
use roc_error_macros::{internal_error, user_error};
|
use roc_error_macros::{internal_error, user_error};
|
||||||
use roc_fmt::MigrationFlags;
|
|
||||||
use roc_gen_dev::AssemblyBackendMode;
|
use roc_gen_dev::AssemblyBackendMode;
|
||||||
use roc_gen_llvm::llvm::build::LlvmBackendMode;
|
use roc_gen_llvm::llvm::build::LlvmBackendMode;
|
||||||
use roc_load::{LoadingProblem, Threading};
|
use roc_load::{LoadingProblem, Threading};
|
||||||
|
@ -395,10 +394,6 @@ fn main() -> io::Result<()> {
|
||||||
false => FormatMode::WriteToFile,
|
false => FormatMode::WriteToFile,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let flags = MigrationFlags {
|
|
||||||
snakify: migrate,
|
|
||||||
parens_and_commas: migrate,
|
|
||||||
};
|
|
||||||
|
|
||||||
if from_stdin && matches!(format_mode, FormatMode::WriteToFile) {
|
if from_stdin && matches!(format_mode, FormatMode::WriteToFile) {
|
||||||
eprintln!("When using the --stdin flag, either the --check or the --stdout flag must also be specified. (Otherwise, it's unclear what filename to write to!)");
|
eprintln!("When using the --stdin flag, either the --check or the --stdout flag must also be specified. (Otherwise, it's unclear what filename to write to!)");
|
||||||
|
@ -451,7 +446,7 @@ fn main() -> io::Result<()> {
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
match format_src(&arena, src, flags) {
|
match format_src(&arena, src, migrate) {
|
||||||
Ok(formatted_src) => {
|
Ok(formatted_src) => {
|
||||||
match format_mode {
|
match format_mode {
|
||||||
FormatMode::CheckOnly => {
|
FormatMode::CheckOnly => {
|
||||||
|
@ -483,7 +478,7 @@ fn main() -> io::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match format_files(roc_files, format_mode, flags) {
|
match format_files(roc_files, format_mode, migrate) {
|
||||||
Ok(()) => 0,
|
Ok(()) => 0,
|
||||||
Err(message) => {
|
Err(message) => {
|
||||||
eprintln!("{message}");
|
eprintln!("{message}");
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub struct Buf<'a> {
|
||||||
flags: MigrationFlags,
|
flags: MigrationFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, Default)]
|
||||||
pub struct MigrationFlags {
|
pub struct MigrationFlags {
|
||||||
pub snakify: bool,
|
pub snakify: bool,
|
||||||
pub parens_and_commas: bool,
|
pub parens_and_commas: bool,
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use roc_module::called_via::UnaryOp;
|
use bumpalo::collections::String;
|
||||||
|
use bumpalo::Bump;
|
||||||
|
use roc_module::called_via::{Associativity, BinOp, UnaryOp};
|
||||||
use roc_parse::{
|
use roc_parse::{
|
||||||
ast::{
|
ast::{
|
||||||
AbilityImpls, AssignedField, Base, Collection, Defs, Expr, FunctionArrow, Header,
|
AbilityImpls, AssignedField, Base, Collection, CommentOrNewline, Defs, Expr, ExtractSpaces,
|
||||||
ImplementsAbilities, ImplementsAbility, ImplementsClause, ImportAlias, ImportAsKeyword,
|
FunctionArrow, Header, ImplementsAbilities, ImplementsAbility, ImplementsClause,
|
||||||
ImportExposingKeyword, ImportedModuleName, IngestedFileAnnotation, IngestedFileImport,
|
ImportAlias, ImportAsKeyword, ImportExposingKeyword, ImportedModuleName,
|
||||||
ModuleImport, ModuleImportParams, Pattern, Spaced, Spaces, SpacesBefore, Tag,
|
IngestedFileAnnotation, IngestedFileImport, ModuleImport, ModuleImportParams, Pattern,
|
||||||
TypeAnnotation, TypeDef, TypeHeader, TypeVar, ValueDef,
|
Spaced, Spaces, SpacesBefore, Tag, TypeAnnotation, TypeDef, TypeHeader, TypeVar, ValueDef,
|
||||||
},
|
},
|
||||||
header::{
|
header::{
|
||||||
AppHeader, ExposedName, HostedHeader, Keyword, KeywordItem, ModuleHeader, ModuleName,
|
AppHeader, ExposedName, HostedHeader, Keyword, KeywordItem, ModuleHeader, ModuleName,
|
||||||
|
@ -25,7 +27,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
pattern::snakify_camel_ident,
|
pattern::snakify_camel_ident,
|
||||||
spaces::fmt_spaces,
|
spaces::fmt_spaces,
|
||||||
Buf,
|
Buf, MigrationFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
@ -76,7 +78,7 @@ impl<F: Fmt> Fmt for AssignedField<'_, F> {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push_str(":");
|
buf.push_str(":");
|
||||||
buf.spaces(1);
|
buf.spaces(1);
|
||||||
loc1.fmt(buf, indent, Suffix::None)?;
|
loc1.fmt(buf, indent, suffix)?;
|
||||||
}
|
}
|
||||||
AssignedField::OptionalValue(name, comment_or_newlines, loc1) => {
|
AssignedField::OptionalValue(name, comment_or_newlines, loc1) => {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
|
@ -87,7 +89,7 @@ impl<F: Fmt> Fmt for AssignedField<'_, F> {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push_str(":");
|
buf.push_str(":");
|
||||||
buf.spaces(1);
|
buf.spaces(1);
|
||||||
loc1.fmt(buf, indent, Suffix::None)?;
|
loc1.fmt(buf, indent, suffix)?;
|
||||||
}
|
}
|
||||||
AssignedField::IgnoredValue(name, comment_or_newlines, loc1) => {
|
AssignedField::IgnoredValue(name, comment_or_newlines, loc1) => {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
|
@ -99,7 +101,7 @@ impl<F: Fmt> Fmt for AssignedField<'_, F> {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push_str(":");
|
buf.push_str(":");
|
||||||
buf.spaces(1);
|
buf.spaces(1);
|
||||||
loc1.fmt(buf, indent, Suffix::None)?;
|
loc1.fmt(buf, indent, suffix)?;
|
||||||
}
|
}
|
||||||
AssignedField::LabelOnly(name) => {
|
AssignedField::LabelOnly(name) => {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
|
@ -127,13 +129,13 @@ pub fn fmt_pattern(
|
||||||
match pat {
|
match pat {
|
||||||
Pattern::Identifier { ident } => {
|
Pattern::Identifier { ident } => {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push_str(ident);
|
snakify_camel_ident(buf, ident);
|
||||||
}
|
}
|
||||||
Pattern::QualifiedIdentifier { module_name, ident } => {
|
Pattern::QualifiedIdentifier { module_name, ident } => {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push_str(module_name);
|
buf.push_str(module_name);
|
||||||
buf.push('.');
|
buf.push('.');
|
||||||
buf.push_str(ident);
|
snakify_camel_ident(buf, ident);
|
||||||
}
|
}
|
||||||
Pattern::Tag(tag) => {
|
Pattern::Tag(tag) => {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
|
@ -145,16 +147,31 @@ pub fn fmt_pattern(
|
||||||
}
|
}
|
||||||
Pattern::Apply(loc, locs) => {
|
Pattern::Apply(loc, locs) => {
|
||||||
fmt_pattern(buf, indent, &loc.value, Suffix::OpenRound)?;
|
fmt_pattern(buf, indent, &loc.value, Suffix::OpenRound)?;
|
||||||
for loc in locs.iter() {
|
for (i, loc) in locs.iter().enumerate() {
|
||||||
fmt_pattern(buf, indent, &loc.value, Suffix::Comma)?;
|
let is_last = i == locs.len() - 1;
|
||||||
|
fmt_pattern(
|
||||||
|
buf,
|
||||||
|
indent,
|
||||||
|
&loc.value,
|
||||||
|
if is_last { Suffix::None } else { Suffix::Comma },
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push(')');
|
buf.push(')');
|
||||||
}
|
}
|
||||||
Pattern::PncApply(loc, collection) => {
|
Pattern::PncApply(loc, collection) => {
|
||||||
fmt_pattern(buf, indent, &loc.value, Suffix::OpenRound)?;
|
fmt_pattern(buf, indent, &loc.value, Suffix::OpenRound)?;
|
||||||
for loc in collection.iter() {
|
for (i, loc) in collection.iter().enumerate() {
|
||||||
fmt_pattern(buf, indent, &loc.value, Suffix::Comma)?;
|
let is_last = i == collection.len() - 1;
|
||||||
|
fmt_pattern(
|
||||||
|
buf,
|
||||||
|
indent,
|
||||||
|
&loc.value,
|
||||||
|
if is_last { Suffix::None } else { Suffix::Comma },
|
||||||
|
)?;
|
||||||
|
if !is_last {
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !collection.final_comments().is_empty() {
|
if !collection.final_comments().is_empty() {
|
||||||
fmt_spaces(buf, collection.final_comments().iter(), indent);
|
fmt_spaces(buf, collection.final_comments().iter(), indent);
|
||||||
|
@ -325,11 +342,7 @@ pub fn fmt_expr(
|
||||||
buf.push_str(module_name);
|
buf.push_str(module_name);
|
||||||
buf.push('.');
|
buf.push('.');
|
||||||
}
|
}
|
||||||
if buf.flags().snakify {
|
|
||||||
snakify_camel_ident(buf, ident);
|
snakify_camel_ident(buf, ident);
|
||||||
} else {
|
|
||||||
buf.push_str(ident);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Expr::Underscore(name) => {
|
Expr::Underscore(name) => {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
|
@ -465,18 +478,34 @@ pub fn fmt_expr(
|
||||||
Expr::LowLevelDbg(..) => todo!(),
|
Expr::LowLevelDbg(..) => todo!(),
|
||||||
Expr::Apply(func, args, _) => {
|
Expr::Apply(func, args, _) => {
|
||||||
fmt_expr(buf, indent, &func.value, Suffix::OpenRound)?;
|
fmt_expr(buf, indent, &func.value, Suffix::OpenRound)?;
|
||||||
for arg in *args {
|
for (i, arg) in args.iter().enumerate() {
|
||||||
// TODO: make the suffix depend on whether we're multiline
|
let is_last = i == args.len() - 1;
|
||||||
fmt_expr(buf, indent, &arg.value, Suffix::Comma)?;
|
fmt_expr(
|
||||||
|
buf,
|
||||||
|
indent,
|
||||||
|
&arg.value,
|
||||||
|
if is_last { Suffix::None } else { Suffix::Comma },
|
||||||
|
)?;
|
||||||
|
if !is_last {
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push(')');
|
buf.push(')');
|
||||||
}
|
}
|
||||||
Expr::PncApply(func, collection) => {
|
Expr::PncApply(func, collection) => {
|
||||||
fmt_expr(buf, indent, &func.value, Suffix::OpenRound)?;
|
fmt_expr(buf, indent, &func.value, Suffix::OpenRound)?;
|
||||||
for arg in collection.iter() {
|
for (i, arg) in collection.iter().enumerate() {
|
||||||
// TODO: make the suffix depend on whether we're multiline
|
let is_last = i == collection.len() - 1;
|
||||||
fmt_expr(buf, indent, &arg.value, Suffix::Comma)?;
|
fmt_expr(
|
||||||
|
buf,
|
||||||
|
indent,
|
||||||
|
&arg.value,
|
||||||
|
if is_last { Suffix::None } else { Suffix::Comma },
|
||||||
|
)?;
|
||||||
|
if !is_last {
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !collection.final_comments().is_empty() {
|
if !collection.final_comments().is_empty() {
|
||||||
fmt_spaces(buf, collection.final_comments().iter(), indent);
|
fmt_spaces(buf, collection.final_comments().iter(), indent);
|
||||||
|
@ -485,14 +514,9 @@ pub fn fmt_expr(
|
||||||
buf.push(')');
|
buf.push(')');
|
||||||
}
|
}
|
||||||
Expr::BinOps(expr_op_pairs, last_expr) => {
|
Expr::BinOps(expr_op_pairs, last_expr) => {
|
||||||
for (expr, op) in *expr_op_pairs {
|
let arena = buf.text.bump();
|
||||||
fmt_expr(buf, indent, &expr.value, Suffix::None)?;
|
let converted = migrate_pizza(buf, arena, expr_op_pairs, **last_expr)?;
|
||||||
buf.spaces(1);
|
fmt_converted_ops(buf, indent, &converted, Suffix::None)?;
|
||||||
buf.indent(indent);
|
|
||||||
push_op(buf, op.value);
|
|
||||||
buf.spaces(1);
|
|
||||||
}
|
|
||||||
fmt_expr(buf, indent, &last_expr.value, Suffix::None)?;
|
|
||||||
}
|
}
|
||||||
Expr::UnaryOp(expr, op) => {
|
Expr::UnaryOp(expr, op) => {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
|
@ -528,10 +552,11 @@ pub fn fmt_expr(
|
||||||
}
|
}
|
||||||
Expr::When(cond, when_branchs) => {
|
Expr::When(cond, when_branchs) => {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push_str("when");
|
buf.push_str("match");
|
||||||
buf.spaces(1);
|
buf.spaces(1);
|
||||||
fmt_expr(buf, indent, &cond.value, Suffix::None)?;
|
fmt_expr(buf, indent, &cond.value, Suffix::None)?;
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
|
buf.spaces(1);
|
||||||
buf.push('{');
|
buf.push('{');
|
||||||
buf.ensure_ends_with_newline();
|
buf.ensure_ends_with_newline();
|
||||||
for branch in when_branchs.iter() {
|
for branch in when_branchs.iter() {
|
||||||
|
@ -599,6 +624,447 @@ pub fn fmt_expr(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum MigratedBinOp<'a> {
|
||||||
|
BinOp {
|
||||||
|
lhs: &'a MigratedBinOp<'a>,
|
||||||
|
op: BinOp,
|
||||||
|
rhs: &'a MigratedBinOp<'a>,
|
||||||
|
},
|
||||||
|
Parens(&'a MigratedBinOp<'a>),
|
||||||
|
StaticDispatch {
|
||||||
|
lhs: &'a MigratedBinOp<'a>,
|
||||||
|
before: &'a [CommentOrNewline<'a>],
|
||||||
|
func: &'a str,
|
||||||
|
args: &'a [Expr<'a>],
|
||||||
|
after: &'a [CommentOrNewline<'a>],
|
||||||
|
},
|
||||||
|
FuncStaticDispatch {
|
||||||
|
lhs: &'a MigratedBinOp<'a>,
|
||||||
|
before: &'a [CommentOrNewline<'a>],
|
||||||
|
func: &'a Expr<'a>,
|
||||||
|
args: &'a [Expr<'a>],
|
||||||
|
after: &'a [CommentOrNewline<'a>],
|
||||||
|
},
|
||||||
|
Expr(Expr<'a>),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_ops<'a>(
|
||||||
|
buf: &Buf<'a>,
|
||||||
|
arena: &'a Bump,
|
||||||
|
stack: &mut Vec<MigratedBinOp<'a>>,
|
||||||
|
ops: &mut Vec<BinOp>,
|
||||||
|
min_precedence: u8,
|
||||||
|
) -> Result<(), MigrateError> {
|
||||||
|
while let Some(&op) = ops.last() {
|
||||||
|
if op.precedence() <= min_precedence
|
||||||
|
&& (op.associativity() == Associativity::RightAssociative
|
||||||
|
|| op.precedence() < min_precedence)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ops.pop();
|
||||||
|
|
||||||
|
let rhs = stack.pop().unwrap();
|
||||||
|
let lhs = stack.pop().unwrap();
|
||||||
|
|
||||||
|
let result = match op {
|
||||||
|
BinOp::Pizza => {
|
||||||
|
// Need to migrate to StaticDispatch or FuncStaticDispatch!
|
||||||
|
match rhs {
|
||||||
|
MigratedBinOp::Expr(expr) => {
|
||||||
|
let expr = expr.extract_spaces();
|
||||||
|
match expr.item {
|
||||||
|
Expr::Apply(func, args, _) => {
|
||||||
|
if let Some(name) = is_staticable(buf, &func.value) {
|
||||||
|
MigratedBinOp::StaticDispatch {
|
||||||
|
lhs: maybe_parens(arena, lhs),
|
||||||
|
before: expr.before,
|
||||||
|
func: arena.alloc_str(name),
|
||||||
|
args: arena.alloc_slice_fill_iter(
|
||||||
|
args.iter().map(|arg| arg.value),
|
||||||
|
),
|
||||||
|
after: expr.after,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MigratedBinOp::FuncStaticDispatch {
|
||||||
|
lhs: maybe_parens(arena, lhs),
|
||||||
|
before: expr.before,
|
||||||
|
func: arena.alloc(func.value),
|
||||||
|
args: arena.alloc_slice_fill_iter(
|
||||||
|
args.iter().map(|arg| arg.value),
|
||||||
|
),
|
||||||
|
after: expr.after,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Var { module_name, ident } => {
|
||||||
|
let ident = if buf.flags.snakify {
|
||||||
|
snakify_camel_ident_in_bump(buf.text.bump(), ident)
|
||||||
|
.into_bump_str()
|
||||||
|
} else {
|
||||||
|
ident
|
||||||
|
};
|
||||||
|
if is_static_method(module_name, ident) {
|
||||||
|
MigratedBinOp::StaticDispatch {
|
||||||
|
lhs: maybe_parens(arena, lhs),
|
||||||
|
before: expr.before,
|
||||||
|
func: arena.alloc_str(ident),
|
||||||
|
args: &[],
|
||||||
|
after: expr.after,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MigratedBinOp::FuncStaticDispatch {
|
||||||
|
lhs: maybe_parens(arena, lhs),
|
||||||
|
before: expr.before,
|
||||||
|
func: arena.alloc(Expr::Var { module_name, ident }),
|
||||||
|
args: &[],
|
||||||
|
after: expr.after,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return Err(MigrateError::PizzaOpRhsNotSupported),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return Err(MigrateError::PizzaOpRhsNotSupported),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => MigratedBinOp::BinOp {
|
||||||
|
lhs: arena.alloc(lhs),
|
||||||
|
op,
|
||||||
|
rhs: arena.alloc(rhs),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
stack.push(result);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maybe_parens<'a>(arena: &'a Bump, lhs: MigratedBinOp<'a>) -> &'a MigratedBinOp<'a> {
|
||||||
|
match lhs {
|
||||||
|
MigratedBinOp::Parens(_)
|
||||||
|
| MigratedBinOp::StaticDispatch { .. }
|
||||||
|
| MigratedBinOp::FuncStaticDispatch { .. }
|
||||||
|
| MigratedBinOp::Expr(_) => arena.alloc(lhs),
|
||||||
|
MigratedBinOp::BinOp { .. } => arena.alloc(MigratedBinOp::Parens(arena.alloc(lhs))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_staticable<'a>(buf: &Buf<'a>, value: &Expr<'a>) -> Option<&'a str> {
|
||||||
|
match value {
|
||||||
|
Expr::Var { module_name, ident } => {
|
||||||
|
let ident = if buf.flags.snakify {
|
||||||
|
snakify_camel_ident_in_bump(buf.text.bump(), ident).into_bump_str()
|
||||||
|
} else {
|
||||||
|
ident
|
||||||
|
};
|
||||||
|
if is_static_method(module_name, ident) {
|
||||||
|
Some(ident)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_static_method(module_name: &str, ident: &str) -> bool {
|
||||||
|
match module_name {
|
||||||
|
"Str" => matches!(
|
||||||
|
ident,
|
||||||
|
"concat"
|
||||||
|
| "is_empty"
|
||||||
|
| "join_with"
|
||||||
|
| "split_on"
|
||||||
|
| "repeat"
|
||||||
|
| "count_utf8_bytes"
|
||||||
|
| "to_utf8"
|
||||||
|
| "starts_with"
|
||||||
|
| "ends_with"
|
||||||
|
| "trim"
|
||||||
|
| "trim_start"
|
||||||
|
| "trim_end"
|
||||||
|
| "to_dec"
|
||||||
|
| "to_f64"
|
||||||
|
| "to_f32"
|
||||||
|
| "to_u128"
|
||||||
|
| "to_i128"
|
||||||
|
| "to_u64"
|
||||||
|
| "to_i64"
|
||||||
|
| "to_u32"
|
||||||
|
| "to_i32"
|
||||||
|
| "to_u16"
|
||||||
|
| "to_i16"
|
||||||
|
| "to_u8"
|
||||||
|
| "to_i8"
|
||||||
|
| "replace_each"
|
||||||
|
| "replace_first"
|
||||||
|
| "replace_last"
|
||||||
|
| "split_first"
|
||||||
|
| "split_last"
|
||||||
|
| "walk_utf8"
|
||||||
|
| "walk_utf8_with_index"
|
||||||
|
| "reserve"
|
||||||
|
| "release_excess_capacity"
|
||||||
|
| "with_prefix"
|
||||||
|
| "contains"
|
||||||
|
| "drop_prefix"
|
||||||
|
| "drop_suffix"
|
||||||
|
| "with_ascii_lowercased"
|
||||||
|
| "with_ascii_uppercased"
|
||||||
|
| "caseless_ascii_equals"
|
||||||
|
),
|
||||||
|
|
||||||
|
// TODO: other modules
|
||||||
|
"List" => matches!(
|
||||||
|
ident,
|
||||||
|
"is_empty"
|
||||||
|
| "get"
|
||||||
|
| "set"
|
||||||
|
| "replace"
|
||||||
|
| "update"
|
||||||
|
| "append"
|
||||||
|
| "append_if_ok"
|
||||||
|
| "prepend"
|
||||||
|
| "prepend_if_ok"
|
||||||
|
| "map"
|
||||||
|
| "len"
|
||||||
|
| "walk_backwards"
|
||||||
|
| "concat"
|
||||||
|
| "first"
|
||||||
|
| "single"
|
||||||
|
| "repeat"
|
||||||
|
| "reverse"
|
||||||
|
| "join"
|
||||||
|
| "keep_if"
|
||||||
|
| "contains"
|
||||||
|
| "sum"
|
||||||
|
| "walk"
|
||||||
|
| "last"
|
||||||
|
| "keep_oks"
|
||||||
|
| "keep_errs"
|
||||||
|
| "map_with_index"
|
||||||
|
| "map2"
|
||||||
|
| "map3"
|
||||||
|
| "product"
|
||||||
|
| "walk_with_index"
|
||||||
|
| "walk_until"
|
||||||
|
| "walk_with_index_until"
|
||||||
|
| "walk_from"
|
||||||
|
| "walk_from_until"
|
||||||
|
| "range"
|
||||||
|
| "sort_with"
|
||||||
|
| "swap"
|
||||||
|
| "drop_at"
|
||||||
|
| "min"
|
||||||
|
| "max"
|
||||||
|
| "map4"
|
||||||
|
| "map_try"
|
||||||
|
| "walk_try"
|
||||||
|
| "join_map"
|
||||||
|
| "any"
|
||||||
|
| "take_first"
|
||||||
|
| "take_last"
|
||||||
|
| "drop_first"
|
||||||
|
| "drop_last"
|
||||||
|
| "find_first"
|
||||||
|
| "find_last"
|
||||||
|
| "find_first_index"
|
||||||
|
| "find_last_index"
|
||||||
|
| "sublist"
|
||||||
|
| "intersperse"
|
||||||
|
| "split_at"
|
||||||
|
| "split_on"
|
||||||
|
| "split_on_list"
|
||||||
|
| "split_first"
|
||||||
|
| "split_last"
|
||||||
|
| "starts_with"
|
||||||
|
| "ends_with"
|
||||||
|
| "all"
|
||||||
|
| "drop_if"
|
||||||
|
| "sort_asc"
|
||||||
|
| "sort_desc"
|
||||||
|
| "reserve"
|
||||||
|
| "release_excess_capacity"
|
||||||
|
| "walk_backwards_until"
|
||||||
|
| "count_if"
|
||||||
|
| "chunks_of"
|
||||||
|
| "concat_utf8"
|
||||||
|
| "for_each!"
|
||||||
|
| "for_each_try!"
|
||||||
|
| "walk!"
|
||||||
|
| "walk_try!"
|
||||||
|
),
|
||||||
|
"Dict" => {
|
||||||
|
matches!(
|
||||||
|
ident,
|
||||||
|
"clear"
|
||||||
|
| "capacity"
|
||||||
|
| "reserve"
|
||||||
|
| "release_excess_capacity"
|
||||||
|
| "len"
|
||||||
|
| "is_empty"
|
||||||
|
| "get"
|
||||||
|
| "contains"
|
||||||
|
| "insert"
|
||||||
|
| "remove"
|
||||||
|
| "update"
|
||||||
|
| "walk"
|
||||||
|
| "walk_until"
|
||||||
|
| "keep_if"
|
||||||
|
| "drop_if"
|
||||||
|
| "to_list"
|
||||||
|
| "keys"
|
||||||
|
| "values"
|
||||||
|
| "insert_all"
|
||||||
|
| "keep_shared"
|
||||||
|
| "remove_all"
|
||||||
|
| "map"
|
||||||
|
| "join_map"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn migrate_pizza<'a>(
|
||||||
|
buf: &Buf<'a>,
|
||||||
|
arena: &'a Bump,
|
||||||
|
expr_op_pairs: &[(Loc<Expr<'a>>, Loc<BinOp>)],
|
||||||
|
last_expr: Loc<Expr<'a>>,
|
||||||
|
) -> Result<MigratedBinOp<'a>, MigrateError> {
|
||||||
|
println!(
|
||||||
|
"Starting migrate_pizza with {} expr_op_pairs",
|
||||||
|
expr_op_pairs.len()
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut stack: Vec<MigratedBinOp<'a>> = Vec::new();
|
||||||
|
let mut ops: Vec<BinOp> = Vec::new();
|
||||||
|
|
||||||
|
for (expr, op) in expr_op_pairs {
|
||||||
|
println!("Processing expression: {:?}", expr.value);
|
||||||
|
stack.push(MigratedBinOp::Expr(expr.value));
|
||||||
|
apply_ops(buf, arena, &mut stack, &mut ops, op.value.precedence())?;
|
||||||
|
|
||||||
|
println!("Pushing operator onto stack: {:?}", op.value);
|
||||||
|
ops.push(op.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push the last expression onto the stack
|
||||||
|
println!("Pushing last expression onto stack: {:?}", last_expr.value);
|
||||||
|
stack.push(MigratedBinOp::Expr(last_expr.value));
|
||||||
|
|
||||||
|
// Apply all remaining operators
|
||||||
|
println!("Applying all remaining operators (min_precedence: 0)");
|
||||||
|
apply_ops(buf, arena, &mut stack, &mut ops, 0)?;
|
||||||
|
println!("Final stack size: {}", stack.len());
|
||||||
|
|
||||||
|
// The final result should be at the top of the stack
|
||||||
|
let result = stack.pop().unwrap();
|
||||||
|
println!("Returning final result: {:?}", result);
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fmt_converted_ops(
|
||||||
|
buf: &mut Buf,
|
||||||
|
indent: u16,
|
||||||
|
converted: &MigratedBinOp,
|
||||||
|
suffix: Suffix,
|
||||||
|
) -> Result<(), MigrateError> {
|
||||||
|
match converted {
|
||||||
|
MigratedBinOp::BinOp { lhs, op, rhs } => {
|
||||||
|
// Format left-hand side
|
||||||
|
fmt_converted_ops(buf, indent, lhs, Suffix::None)?;
|
||||||
|
|
||||||
|
// Format operator
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.spaces(1);
|
||||||
|
push_op(buf, *op);
|
||||||
|
buf.spaces(1);
|
||||||
|
|
||||||
|
// Format right-hand side
|
||||||
|
fmt_converted_ops(buf, indent, rhs, suffix)?;
|
||||||
|
}
|
||||||
|
MigratedBinOp::Expr(expr) => {
|
||||||
|
fmt_expr(buf, indent, expr, suffix)?;
|
||||||
|
}
|
||||||
|
MigratedBinOp::Parens(inner) => {
|
||||||
|
buf.push('(');
|
||||||
|
fmt_converted_ops(buf, indent, inner, Suffix::None)?;
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push(')');
|
||||||
|
fmt_suffix(buf, indent, suffix);
|
||||||
|
}
|
||||||
|
MigratedBinOp::StaticDispatch {
|
||||||
|
lhs,
|
||||||
|
before,
|
||||||
|
func,
|
||||||
|
args,
|
||||||
|
after,
|
||||||
|
} => {
|
||||||
|
// lhs.func(args)
|
||||||
|
fmt_converted_ops(buf, indent, lhs, Suffix::None)?;
|
||||||
|
if !before.is_empty() {
|
||||||
|
fmt_spaces(buf, before.iter(), indent);
|
||||||
|
}
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push('.');
|
||||||
|
buf.push_str(func);
|
||||||
|
buf.push('(');
|
||||||
|
for (i, arg) in args.iter().enumerate() {
|
||||||
|
fmt_expr(buf, indent, arg, Suffix::None)?;
|
||||||
|
if i != args.len() - 1 {
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push(',');
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push(')');
|
||||||
|
fmt_suffix(buf, indent, suffix);
|
||||||
|
if !after.is_empty() {
|
||||||
|
fmt_spaces(buf, after.iter(), indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MigratedBinOp::FuncStaticDispatch {
|
||||||
|
lhs,
|
||||||
|
before,
|
||||||
|
func,
|
||||||
|
args,
|
||||||
|
after,
|
||||||
|
} => {
|
||||||
|
// lhs.(func)(args)
|
||||||
|
fmt_converted_ops(buf, indent, lhs, Suffix::None)?;
|
||||||
|
if !before.is_empty() {
|
||||||
|
fmt_spaces(buf, before.iter(), indent);
|
||||||
|
}
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push('.');
|
||||||
|
buf.push('(');
|
||||||
|
fmt_expr(buf, indent, func, Suffix::None)?;
|
||||||
|
buf.push(')');
|
||||||
|
buf.push('(');
|
||||||
|
for (i, arg) in args.iter().enumerate() {
|
||||||
|
fmt_expr(buf, indent, arg, Suffix::None)?;
|
||||||
|
if i != args.len() - 1 {
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push(',');
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push(')');
|
||||||
|
fmt_suffix(buf, indent, suffix);
|
||||||
|
if !after.is_empty() {
|
||||||
|
fmt_spaces(buf, after.iter(), indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fmt_expr_top_level(
|
pub fn fmt_expr_top_level(
|
||||||
buf: &mut Buf<'_>,
|
buf: &mut Buf<'_>,
|
||||||
indent: u16,
|
indent: u16,
|
||||||
|
@ -691,8 +1157,16 @@ fn fmt_collection<F: Fmt>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for item in collection.iter() {
|
for (i, item) in collection.iter().enumerate() {
|
||||||
item.fmt(buf, indent + 4, Suffix::Comma)?;
|
let is_last = i == collection.len() - 1 && tail.is_none();
|
||||||
|
item.fmt(
|
||||||
|
buf,
|
||||||
|
indent + 4,
|
||||||
|
if is_last { Suffix::None } else { Suffix::Comma },
|
||||||
|
)?;
|
||||||
|
if !is_last {
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(tail) = tail {
|
if let Some(tail) = tail {
|
||||||
|
@ -743,12 +1217,22 @@ impl Fmt for TypeHeader<'_> {
|
||||||
fn fmt(&self, buf: &mut Buf, indent: u16, suffix: Suffix) -> Result<(), MigrateError> {
|
fn fmt(&self, buf: &mut Buf, indent: u16, suffix: Suffix) -> Result<(), MigrateError> {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push_str(self.name.value);
|
buf.push_str(self.name.value);
|
||||||
|
if !self.vars.is_empty() {
|
||||||
buf.push('(');
|
buf.push('(');
|
||||||
for arg in self.vars {
|
for (i, arg) in self.vars.iter().enumerate() {
|
||||||
arg.fmt(buf, indent, Suffix::Comma)?;
|
let is_last = i == self.vars.len() - 1;
|
||||||
|
arg.fmt(
|
||||||
|
buf,
|
||||||
|
indent,
|
||||||
|
if is_last { Suffix::None } else { Suffix::Comma },
|
||||||
|
)?;
|
||||||
|
if !is_last {
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push(')');
|
buf.push(')');
|
||||||
|
}
|
||||||
fmt_suffix(buf, indent, suffix);
|
fmt_suffix(buf, indent, suffix);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -762,8 +1246,16 @@ impl Fmt for Tag<'_> {
|
||||||
buf.push_str(name.value);
|
buf.push_str(name.value);
|
||||||
if !args.is_empty() {
|
if !args.is_empty() {
|
||||||
buf.push('(');
|
buf.push('(');
|
||||||
for arg in args.iter() {
|
for (i, arg) in args.iter().enumerate() {
|
||||||
arg.fmt(buf, indent, Suffix::Comma)?;
|
let is_last = i == args.len() - 1;
|
||||||
|
arg.fmt(
|
||||||
|
buf,
|
||||||
|
indent,
|
||||||
|
if is_last { Suffix::None } else { Suffix::Comma },
|
||||||
|
)?;
|
||||||
|
if !is_last {
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push(')');
|
buf.push(')');
|
||||||
|
@ -788,8 +1280,16 @@ impl Fmt for TypeAnnotation<'_> {
|
||||||
fn fmt(&self, buf: &mut Buf, indent: u16, suffix: Suffix) -> Result<(), MigrateError> {
|
fn fmt(&self, buf: &mut Buf, indent: u16, suffix: Suffix) -> Result<(), MigrateError> {
|
||||||
match self {
|
match self {
|
||||||
TypeAnnotation::Function(args, function_arrow, res) => {
|
TypeAnnotation::Function(args, function_arrow, res) => {
|
||||||
for arg in args.iter() {
|
for (i, arg) in args.iter().enumerate() {
|
||||||
arg.fmt(buf, indent, Suffix::Comma)?;
|
let is_last = i == args.len() - 1;
|
||||||
|
arg.fmt(
|
||||||
|
buf,
|
||||||
|
indent,
|
||||||
|
if is_last { Suffix::None } else { Suffix::Comma },
|
||||||
|
)?;
|
||||||
|
if !is_last {
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
match function_arrow {
|
match function_arrow {
|
||||||
FunctionArrow::Pure => {
|
FunctionArrow::Pure => {
|
||||||
|
@ -811,8 +1311,16 @@ impl Fmt for TypeAnnotation<'_> {
|
||||||
buf.push_str(func);
|
buf.push_str(func);
|
||||||
if !locs.is_empty() {
|
if !locs.is_empty() {
|
||||||
buf.push('(');
|
buf.push('(');
|
||||||
for loc in locs.iter() {
|
for (i, loc) in locs.iter().enumerate() {
|
||||||
loc.fmt(buf, indent, Suffix::Comma)?;
|
let is_last = i == locs.len() - 1;
|
||||||
|
loc.fmt(
|
||||||
|
buf,
|
||||||
|
indent,
|
||||||
|
if is_last { Suffix::None } else { Suffix::Comma },
|
||||||
|
)?;
|
||||||
|
if !is_last {
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push(')');
|
buf.push(')');
|
||||||
|
@ -865,8 +1373,7 @@ impl Fmt for TypeAnnotation<'_> {
|
||||||
buf.push_str("_");
|
buf.push_str("_");
|
||||||
}
|
}
|
||||||
TypeAnnotation::Wildcard => {
|
TypeAnnotation::Wildcard => {
|
||||||
buf.indent(indent);
|
return Err(MigrateError::WildcardTypeNotSupported);
|
||||||
buf.push_str("*");
|
|
||||||
}
|
}
|
||||||
TypeAnnotation::Where(left, clauses) => {
|
TypeAnnotation::Where(left, clauses) => {
|
||||||
left.fmt(buf, indent, Suffix::None)?;
|
left.fmt(buf, indent, Suffix::None)?;
|
||||||
|
@ -1022,6 +1529,11 @@ impl Fmt for TypeDef<'_> {
|
||||||
typ,
|
typ,
|
||||||
derived,
|
derived,
|
||||||
} => {
|
} => {
|
||||||
|
if true {
|
||||||
|
// current new compiler doesn't support opaque types
|
||||||
|
// TODO: fix this!
|
||||||
|
return Err(MigrateError::OpaqueNotSupported);
|
||||||
|
}
|
||||||
header.fmt(buf, indent, Suffix::None)?;
|
header.fmt(buf, indent, Suffix::None)?;
|
||||||
buf.push_str(" :=");
|
buf.push_str(" :=");
|
||||||
buf.spaces(1);
|
buf.spaces(1);
|
||||||
|
@ -1046,11 +1558,14 @@ impl Fmt for TypeDef<'_> {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MigrateError {
|
pub enum MigrateError {
|
||||||
AbilitiesNotSupported,
|
AbilitiesNotSupported,
|
||||||
|
WildcardTypeNotSupported,
|
||||||
MalformedIdentNotSupported,
|
MalformedIdentNotSupported,
|
||||||
MalformedPatternNotSupported,
|
MalformedPatternNotSupported,
|
||||||
MalformedPatternIdentNotSupported,
|
MalformedPatternIdentNotSupported,
|
||||||
MalformedPatternAsExprNotSupported,
|
MalformedPatternAsExprNotSupported,
|
||||||
PrecedenceConflictNotSupported,
|
PrecedenceConflictNotSupported,
|
||||||
|
OpaqueNotSupported,
|
||||||
|
PizzaOpRhsNotSupported,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fmt for ValueDef<'_> {
|
impl Fmt for ValueDef<'_> {
|
||||||
|
@ -1133,6 +1648,7 @@ impl Fmt for IngestedFileImport<'_> {
|
||||||
|
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push_str("import");
|
buf.push_str("import");
|
||||||
|
buf.spaces(1);
|
||||||
|
|
||||||
let indent = indent + 4;
|
let indent = indent + 4;
|
||||||
|
|
||||||
|
@ -1236,6 +1752,7 @@ impl Fmt for ModuleImport<'_> {
|
||||||
|
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push_str("import");
|
buf.push_str("import");
|
||||||
|
buf.spaces(1);
|
||||||
|
|
||||||
if !before_name.is_empty() {
|
if !before_name.is_empty() {
|
||||||
fmt_spaces(buf, before_name.iter(), indent);
|
fmt_spaces(buf, before_name.iter(), indent);
|
||||||
|
@ -1250,10 +1767,13 @@ impl Fmt for ModuleImport<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(exposed) = exposed {
|
if let Some(exposed) = exposed {
|
||||||
|
buf.spaces(1);
|
||||||
exposed.keyword.fmt(buf, indent, Suffix::None)?;
|
exposed.keyword.fmt(buf, indent, Suffix::None)?;
|
||||||
|
buf.spaces(1);
|
||||||
fmt_collection(buf, indent, Braces::Square, None, exposed.item, None)?;
|
fmt_collection(buf, indent, Braces::Square, None, exposed.item, None)?;
|
||||||
}
|
}
|
||||||
fmt_suffix(buf, indent, suffix);
|
fmt_suffix(buf, indent, suffix);
|
||||||
|
buf.ensure_ends_with_newline();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1399,3 +1919,9 @@ pub fn fmt_defs(buf: &mut Buf<'_>, defs: &Defs<'_>) -> Result<(), MigrateError>
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn snakify_camel_ident_in_bump<'a>(arena: &'a Bump, string: &str) -> String<'a> {
|
||||||
|
let mut buf = Buf::new_in(arena, MigrationFlags::default());
|
||||||
|
snakify_camel_ident(&mut buf, string);
|
||||||
|
buf.text
|
||||||
|
}
|
||||||
|
|
|
@ -216,7 +216,7 @@ impl BinOp {
|
||||||
ASSOCIATIVITY_TABLE[self as usize]
|
ASSOCIATIVITY_TABLE[self as usize]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn precedence(self) -> u8 {
|
pub fn precedence(self) -> u8 {
|
||||||
const PRECEDENCE_TABLE: [u8; 18] = generate_precedence_table();
|
const PRECEDENCE_TABLE: [u8; 18] = generate_precedence_table();
|
||||||
|
|
||||||
PRECEDENCE_TABLE[self as usize]
|
PRECEDENCE_TABLE[self as usize]
|
||||||
|
|
|
@ -5,6 +5,6 @@ O({p: if
|
||||||
A
|
A
|
||||||
} else {
|
} else {
|
||||||
&m
|
&m
|
||||||
}}, #
|
}} #
|
||||||
) : e
|
) : e
|
||||||
i
|
i
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
N((implements),h,(0),) : B
|
N((implements), h, (0)) : B
|
||||||
T
|
T
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
N(-0,T,) : A
|
N(-0, T) : A
|
||||||
zT
|
zT
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
B(@A,) : w
|
B(@A) : w
|
||||||
#
|
#
|
||||||
@A = e
|
@A = e
|
||||||
i
|
i
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
Zx((e #
|
Zx((e #
|
||||||
),f,) : i
|
), f) : i
|
||||||
s
|
s
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
U((b(a,)),) : b
|
U((b(a))) : b
|
||||||
a
|
a
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
M({s: s({J&
|
M({s: s({J&
|
||||||
},)},{s: s({J&
|
})}, {s: s({J&
|
||||||
},)},) : p
|
})}) : p
|
||||||
y
|
y
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Q((
|
Q((
|
||||||
"""
|
"""
|
||||||
"""("",)),) : a
|
"""(""))) : a
|
||||||
q
|
q
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
il3(|k| # w#z
|
il3(|k| # w#z
|
||||||
{
|
{
|
||||||
CCC(@C,( # i
|
CCC(@C, ( # i
|
||||||
t!(K,)),) : i
|
t!(K))) : i
|
||||||
C
|
C
|
||||||
},)
|
})
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
M() :
|
M :
|
||||||
r
|
r
|
||||||
h
|
h
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
A( #
|
A( #
|
||||||
p,) : e
|
p) : e
|
||||||
A
|
A
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
K() : #
|
K : #
|
||||||
s
|
s
|
||||||
K
|
K
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
O() : O(z,
|
O : O(z
|
||||||
#
|
#
|
||||||
)
|
)
|
||||||
b #
|
b #
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
8: O(
|
8: O(
|
||||||
{
|
{
|
||||||
},)
|
})
|
||||||
Q
|
Q
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
foo: [True,Perhaps(Thing,),]
|
foo: [True, Perhaps(Thing)]
|
||||||
foo = True
|
foo = True
|
||||||
|
|
||||||
42
|
42
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
launchTheNukes: {}, => Result(Bool,LaunchNukeErr,)
|
launchTheNukes: {} => Result(Bool, LaunchNukeErr)
|
||||||
launchTheNukes = |{}|
|
launchTheNukes = |{}|
|
||||||
crash("todo",)
|
crash("todo")
|
||||||
|
|
||||||
launchTheNukes
|
launchTheNukes
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
x: a
|
x: a
|
||||||
where
|
where
|
||||||
e
|
e
|
||||||
implements K, -> Z
|
implements K -> Z
|
||||||
s
|
s
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
H() : p
|
H : p
|
||||||
#
|
#
|
||||||
s = p
|
s = p
|
||||||
d #
|
d #
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
{l: s, #
|
{l: s #
|
||||||
}: s
|
}: s
|
||||||
o
|
o
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
k:
|
k:
|
||||||
[T,..m
|
[T, ..m
|
||||||
] #
|
] #
|
||||||
D
|
D
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
J() : [
|
J : [
|
||||||
] where e
|
] where e
|
||||||
implements T
|
implements T
|
||||||
i
|
i
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
1: (f,
|
1: (f,
|
||||||
ww, -> p,..e)
|
ww -> p, ..e)
|
||||||
Mh
|
Mh
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{x,y,}: Foo
|
{x, y}: Foo
|
||||||
{x,y,} = {x: "foo"y: 3.14}
|
{x, y} = {x: "foo", y: 3.14}
|
||||||
|
|
||||||
x
|
x
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
UserId(x,): [UserId(I64,),]
|
UserId(x): [UserId(I64)]
|
||||||
UserId(x,) = UserId(42,)
|
UserId(x) = UserId(42)
|
||||||
|
|
||||||
x
|
x
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
(x,y,): Foo
|
(x, y): Foo
|
||||||
(x,y,) = ("foo",3.14,)
|
(x, y) = ("foo", 3.14)
|
||||||
|
|
||||||
x
|
x
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
A(
|
A(
|
||||||
p,) :
|
p) :
|
||||||
e
|
e
|
||||||
A
|
A
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
e: A #
|
e: A #
|
||||||
as H()
|
as H
|
||||||
n
|
n
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
A(
|
A(
|
||||||
e, # g
|
e # g
|
||||||
) : A
|
) : A
|
||||||
AA
|
AA
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
s: eas A()as A()
|
s: eas Aas A
|
||||||
s
|
s
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
g: [T(T, #
|
g: [T(T #
|
||||||
),]
|
)]
|
||||||
D
|
D
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
3: (..n #
|
3: (..n #
|
||||||
), -> n
|
) -> n
|
||||||
0
|
0
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
d: (J,..g
|
d: (J, ..g
|
||||||
)
|
)
|
||||||
2
|
2
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
1: ((),..n)
|
1: ((), ..n)
|
||||||
l
|
l
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
Str.getUnsafe(haystack,haystackIndex,)
|
Str.getUnsafe(haystack, haystackIndex)
|
||||||
==
|
==
|
||||||
Str.getUnsafe(needle,needleIndex,)
|
Str.getUnsafe(needle, needleIndex)
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
!!
|
!!
|
||||||
|w| 2(
|
|w| 2(
|
||||||
n,)
|
n)
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
foo
|
foo
|
||||||
|> Dict.keepIf(|(k,_v,)| List.contains(keysToDelete,k,) |> Bool.not,)
|
.(Dict.keepIf)(|(k, _v)| List.contains(keysToDelete, k).(Bool.not)())
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Whee((12),(34),)
|
Whee((12), (34))
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
a: N({h
|
a: N({h
|
||||||
},)
|
})
|
||||||
g
|
g
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
0({lxtl: (se #
|
0({l xt l: (se #
|
||||||
)},)
|
)})
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Whee(12,34,)
|
Whee(12, 34)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Whee(12,34,)
|
Whee(12, 34)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Ok(a,)
|
Ok(a)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Ok(a,)
|
Ok(a)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
a(b,c,d,)
|
a(b, c, d)
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
i: M((),c,)
|
i: M((), c)
|
||||||
t
|
t
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
whee(12,34,)
|
whee(12, 34)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
whee(12,34,)
|
whee(12, 34)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
-whee(12,foo,)
|
-whee(12, foo)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
!whee(12,foo,)
|
!whee(12, foo)
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
|{x,y,} as point@Location(inner,) as outer|
|
|{x, y} as point@Location(inner) as outer|
|
||||||
crash("",)
|
crash("")
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
e: J
|
e: J
|
||||||
as H(), -> A
|
as H -> A
|
||||||
r
|
r
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
J
|
J
|
||||||
!
|
!
|
||||||
.1(!.0,)
|
.1(!.0)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
whee(1,)
|
whee(1)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
(1,2,3,)
|
(1, 2, 3)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
N < l((r * N),)
|
N < l((r * N))
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
d +
|
d +
|
||||||
(|w| x)(
|
(|w| x)(
|
||||||
x,)
|
x)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
r ^
|
r ^
|
||||||
-f(
|
-f(
|
||||||
#
|
#
|
||||||
-P,)
|
-P)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
t =
|
t =
|
||||||
"""
|
"""
|
||||||
"
|
"
|
||||||
"""("",)
|
"""("")
|
||||||
S
|
S
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
launchTheNukes!(123,)
|
launchTheNukes!(123)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
fxFn!(arg,)
|
fxFn!(arg)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
importP{_: h
|
import P{_: h
|
||||||
}
|
}
|
||||||
|
|
||||||
t!
|
t!
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
|I({p? Y(
|
|I({p? Y(
|
||||||
Y,)?,},[
|
Y)?},[
|
||||||
],)|
|
])|
|
||||||
K # (
|
K # (
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
m0(|w| w?(e,),)
|
m0(|w| w?(e))
|
||||||
/ s
|
/ s
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
|L(z,
|
|L(z
|
||||||
|
|
||||||
)| 42
|
)| 42
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
|{i, #
|
|{i, #
|
||||||
e,}| a
|
e}| a
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
m
|
m
|
||||||
^ (-|w| m)(
|
^ (-|w| m)(
|
||||||
w,)
|
w)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
Model(position,) :
|
Model(position) :
|
||||||
{evaluated: Set(position,)
|
{evaluated: Set(position),
|
||||||
openSet: Set(position,)
|
openSet: Set(position),
|
||||||
costs: Dict.Dict(position,F64,)
|
costs: Dict.Dict(position, F64),
|
||||||
cameFrom: Dict.Dict(position,position,)
|
cameFrom: Dict.Dict(position, position)
|
||||||
}
|
}
|
||||||
|
|
||||||
a
|
a
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
F() : e #
|
F : e #
|
||||||
|
|
||||||
q
|
q
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
dbg(l,) #
|
dbg(l) #
|
||||||
n
|
n
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
PP(P(@P(P(
|
PP(P(@P(P(
|
||||||
P(PPP(P(
|
P(PPP(P(
|
||||||
PPP,),
|
PPP)
|
||||||
),
|
)
|
||||||
),
|
),
|
||||||
PP(mport, # <|"P
|
PP(mport # <|"P
|
||||||
),),
|
))
|
||||||
),),
|
))
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
1: (M,b, # ,
|
1: (M, b, # ,
|
||||||
h, -> g,..e)
|
h -> g, ..e)
|
||||||
h
|
h
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
3 # test!
|
3 # test!
|
||||||
+ 4
|
+ 4
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
|L( #
|
|L( #
|
||||||
i,)| -e
|
i)| -e
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
|LM( #
|
|LM( #
|
||||||
Q,)| f8
|
Q)| f8
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
1(0, #
|
1(0 #
|
||||||
#
|
#
|
||||||
): gi
|
): gi
|
||||||
M
|
M
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
3 # 2 × 2
|
3 # 2 × 2
|
||||||
+ 4
|
+ 4
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
x >
|
x >
|
||||||
x({
|
x({
|
||||||
|
|
||||||
},) < r
|
}) < r
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
_ = crash("",)
|
_ = crash("")
|
||||||
_ = crash("","",)
|
_ = crash("", "")
|
||||||
_ = crash(15,123,)
|
_ = crash(15, 123)
|
||||||
_ = try(foo,(|_| crash("",)),)
|
_ = try(foo, (|_| crash("")))
|
||||||
_ =
|
_ =
|
||||||
{
|
{
|
||||||
_ = crash("",)
|
_ = crash("")
|
||||||
crash
|
crash
|
||||||
}
|
}
|
||||||
|
|
||||||
{f: crash("",)}
|
{f: crash("")}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
1(0( #
|
1(0( #
|
||||||
0,),
|
0)
|
||||||
)(f,): f
|
)(f): f
|
||||||
t
|
t
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
1(ts(0,
|
1(ts(0
|
||||||
|
|
||||||
#
|
#
|
||||||
),
|
)
|
||||||
)(f,): i7f
|
)(f): i7f
|
||||||
e
|
e
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
-
|
-
|
||||||
"""
|
"""
|
||||||
"""()?
|
"""()?
|
||||||
}))(Y,)
|
}))(Y)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
0(
|
0(
|
||||||
#
|
#
|
||||||
f,): f
|
f): f
|
||||||
t
|
t
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
1: w, -> w, -> p
|
1: w -> w -> p
|
||||||
h
|
h
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
dbg(1,)
|
dbg(1)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
dbg(dbg,g,g,)
|
dbg(dbg, g, g)
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
dbg(dbg,
|
dbg(dbg,
|
||||||
a,g,)
|
a, g)
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
dbg(d,z,)
|
dbg(d, z)
|
||||||
dd
|
dd
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
dbg(
|
dbg(
|
||||||
|
|
||||||
izzb,
|
izzb,
|
||||||
interfacesb,)
|
interfacesb)
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
dbg(a / a,)
|
dbg(a / a)
|
||||||
d
|
d
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
({
|
({
|
||||||
(dbg(r,))
|
(dbg(r))
|
||||||
r
|
r
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
dbg (5,
|
dbg (5,
|
||||||
666,)
|
666)
|
||||||
|
|
||||||
4
|
4
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
dbg
|
dbg
|
||||||
(q(
|
(q(
|
||||||
qt,))
|
qt))
|
||||||
|
|
||||||
g(
|
g(
|
||||||
qt,)
|
qt)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
launchTheNukes! = |{}|
|
launchTheNukes! = |{}|
|
||||||
boom
|
boom
|
||||||
|
|
||||||
launchTheNukes!({},)
|
launchTheNukes!({})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
e =
|
e =
|
||||||
"""
|
"""
|
||||||
"""(a,)
|
"""(a)
|
||||||
p
|
p
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
main =
|
main =
|
||||||
{
|
{
|
||||||
a = "Foo"
|
a = "Foo"
|
||||||
Stdout.line?(a,)
|
Stdout.line?(a)
|
||||||
|
|
||||||
printBar?
|
printBar?
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,5 @@ main =
|
||||||
printBar =
|
printBar =
|
||||||
{
|
{
|
||||||
b = "Bar"
|
b = "Bar"
|
||||||
Stdout.line(b,)
|
Stdout.line(b)
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue