use crate::datum::Prefix;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DelimRole {
List,
Vector,
Map,
Ordinary,
}
impl DelimRole {
pub fn is_delimiter(self) -> bool {
self != DelimRole::Ordinary
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BlockComment {
pub open: &'static str,
pub close: &'static str,
pub nestable: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CharSyntax {
HashBackslash,
Backslash,
Question,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HashParen {
Vector,
HashFn,
None,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Dialect {
Scheme,
Clojure,
CommonLisp,
EmacsLisp,
Racket,
Janet,
Hy,
AutoLisp,
Guile,
Phel,
Fennel,
Lfe,
Islisp,
}
#[derive(Debug, Clone)]
pub struct Options {
pub line_comment: char,
pub comma_is_whitespace: bool,
pub block_comment: Option<BlockComment>,
pub datum_comment: bool,
pub discard_underscore: bool,
pub hash_syntax: bool,
pub square: DelimRole,
pub curly: DelimRole,
pub set_literal: bool,
pub regex_literal: bool,
pub tagged_literals: bool,
pub hash_apostrophe: Option<Prefix>,
pub reader_conditional: bool,
pub feature_conditional: bool,
pub read_eval: bool,
pub symbol_escape: bool,
pub booleans: bool,
pub char_syntax: Option<CharSyntax>,
pub hash_paren: HashParen,
pub keyword_colon: bool,
pub hash_keyword: bool,
pub lang_line: bool,
pub shebang_line: bool,
pub piped_symbols: bool,
pub datum_labels: bool,
pub dotted_pairs: bool,
pub quote: Option<char>,
pub quasiquote: Option<char>,
pub unquote: Option<char>,
pub splicing_suffix: char,
pub deref: Option<char>,
pub meta: Option<char>,
pub splice: Option<char>,
pub mutable: Option<char>,
pub short_fn: Option<char>,
pub long_string_backtick: bool,
pub bracket_string: bool,
}
impl Options {
pub fn scheme() -> Self {
Options {
line_comment: ';',
comma_is_whitespace: false,
block_comment: Some(BlockComment {
open: "#|",
close: "|#",
nestable: true,
}),
datum_comment: true,
discard_underscore: false,
hash_syntax: true,
square: DelimRole::List,
curly: DelimRole::Ordinary,
set_literal: false,
regex_literal: false,
tagged_literals: false,
hash_apostrophe: None,
reader_conditional: false,
feature_conditional: false,
read_eval: false,
symbol_escape: false,
booleans: true,
char_syntax: Some(CharSyntax::HashBackslash),
hash_paren: HashParen::Vector,
keyword_colon: false,
piped_symbols: true,
datum_labels: true,
dotted_pairs: true,
hash_keyword: false,
lang_line: false,
shebang_line: false,
quote: Some('\''),
quasiquote: Some('`'),
unquote: Some(','),
splicing_suffix: '@',
deref: None,
meta: None,
splice: None,
mutable: None,
short_fn: None,
long_string_backtick: false,
bracket_string: false,
}
}
pub fn clojure() -> Self {
Options {
line_comment: ';',
comma_is_whitespace: true,
block_comment: None,
datum_comment: false,
discard_underscore: true,
hash_syntax: true,
square: DelimRole::Vector,
curly: DelimRole::Map,
set_literal: true,
regex_literal: true,
tagged_literals: true,
hash_apostrophe: Some(Prefix::VarQuote),
reader_conditional: true,
feature_conditional: false,
read_eval: false,
symbol_escape: false,
booleans: false, char_syntax: Some(CharSyntax::Backslash),
hash_paren: HashParen::HashFn,
keyword_colon: true,
piped_symbols: false,
datum_labels: false,
dotted_pairs: false,
hash_keyword: false,
lang_line: false,
shebang_line: false,
quote: Some('\''),
quasiquote: Some('`'),
unquote: Some('~'),
splicing_suffix: '@',
deref: Some('@'),
meta: Some('^'),
splice: None,
mutable: None,
short_fn: None,
long_string_backtick: false,
bracket_string: false,
}
}
pub fn common_lisp() -> Self {
Options {
line_comment: ';',
comma_is_whitespace: false,
block_comment: Some(BlockComment {
open: "#|",
close: "|#",
nestable: true,
}),
datum_comment: false,
discard_underscore: false,
hash_syntax: true,
square: DelimRole::Ordinary,
curly: DelimRole::Ordinary,
set_literal: false,
regex_literal: false,
tagged_literals: false,
hash_apostrophe: Some(Prefix::FunctionQuote), reader_conditional: false,
feature_conditional: true, read_eval: true, symbol_escape: true, booleans: false, char_syntax: Some(CharSyntax::HashBackslash),
hash_paren: HashParen::Vector, keyword_colon: true, piped_symbols: true, datum_labels: true, dotted_pairs: true,
hash_keyword: false,
lang_line: false,
shebang_line: false,
quote: Some('\''),
quasiquote: Some('`'),
unquote: Some(','),
splicing_suffix: '@',
deref: None,
meta: None,
splice: None,
mutable: None,
short_fn: None,
long_string_backtick: false,
bracket_string: false,
}
}
pub fn emacs_lisp() -> Self {
Options {
line_comment: ';',
comma_is_whitespace: false,
block_comment: None, datum_comment: false,
discard_underscore: false,
hash_syntax: true,
square: DelimRole::Vector, curly: DelimRole::Ordinary,
set_literal: false,
regex_literal: false,
tagged_literals: false,
hash_apostrophe: Some(Prefix::FunctionQuote), reader_conditional: false,
feature_conditional: false,
read_eval: false,
symbol_escape: true,
booleans: false, char_syntax: Some(CharSyntax::Question), hash_paren: HashParen::Vector, keyword_colon: true, piped_symbols: false,
datum_labels: true, dotted_pairs: true,
hash_keyword: false,
lang_line: false,
shebang_line: false,
quote: Some('\''),
quasiquote: Some('`'),
unquote: Some(','),
splicing_suffix: '@',
deref: None,
meta: None,
splice: None,
mutable: None,
short_fn: None,
long_string_backtick: false,
bracket_string: false,
}
}
pub fn racket() -> Self {
Options {
square: DelimRole::List,
curly: DelimRole::List, hash_apostrophe: Some(Prefix::VarQuote), symbol_escape: true,
keyword_colon: false, hash_keyword: true,
lang_line: true,
shebang_line: true,
..Options::scheme()
}
}
pub fn janet() -> Self {
Options {
line_comment: '#',
block_comment: None,
datum_comment: false,
hash_syntax: false, square: DelimRole::List, curly: DelimRole::Map, booleans: false,
char_syntax: None,
hash_paren: HashParen::None,
keyword_colon: true,
piped_symbols: false,
datum_labels: false,
dotted_pairs: false,
quasiquote: Some('~'),
unquote: Some(','),
splice: Some(';'),
mutable: Some('@'), short_fn: Some('|'),
long_string_backtick: true, ..Options::scheme()
}
}
pub fn hy() -> Self {
Options {
block_comment: None,
datum_comment: false,
discard_underscore: true, square: DelimRole::List, curly: DelimRole::Map, set_literal: true, tagged_literals: true, booleans: false, char_syntax: None,
hash_paren: HashParen::None,
keyword_colon: true,
piped_symbols: false,
datum_labels: false,
dotted_pairs: false, unquote: Some('~'), bracket_string: true, ..Options::scheme()
}
}
pub fn autolisp() -> Self {
Options {
block_comment: Some(BlockComment {
open: ";|",
close: "|;",
nestable: false,
}),
datum_comment: false,
hash_syntax: false,
square: DelimRole::Ordinary,
booleans: false, char_syntax: None,
hash_paren: HashParen::None,
piped_symbols: false,
datum_labels: false,
quasiquote: None, unquote: None,
..Options::scheme()
}
}
pub fn guile() -> Self {
Options {
hash_keyword: true, hash_apostrophe: Some(Prefix::VarQuote), ..Options::scheme()
}
}
pub fn phel() -> Self {
Options::clojure()
}
pub fn fennel() -> Self {
Options {
block_comment: None,
datum_comment: false,
square: DelimRole::List, curly: DelimRole::Map, booleans: false, char_syntax: None,
hash_paren: HashParen::HashFn, keyword_colon: false, piped_symbols: false,
datum_labels: false,
dotted_pairs: false, ..Options::scheme()
}
}
pub fn lfe() -> Self {
Options {
block_comment: Some(BlockComment {
open: "#|",
close: "|#",
nestable: false, }),
regex_literal: true, hash_apostrophe: Some(Prefix::FunctionQuote), booleans: false, datum_labels: false,
..Options::scheme()
}
}
pub fn islisp() -> Self {
Options {
square: DelimRole::Ordinary, keyword_colon: true, hash_apostrophe: Some(Prefix::FunctionQuote), booleans: false, datum_labels: false,
..Options::scheme()
}
}
pub fn for_dialect(dialect: Dialect) -> Self {
match dialect {
Dialect::Scheme => Options::scheme(),
Dialect::Clojure => Options::clojure(),
Dialect::CommonLisp => Options::common_lisp(),
Dialect::EmacsLisp => Options::emacs_lisp(),
Dialect::Racket => Options::racket(),
Dialect::Janet => Options::janet(),
Dialect::Hy => Options::hy(),
Dialect::AutoLisp => Options::autolisp(),
Dialect::Guile => Options::guile(),
Dialect::Phel => Options::phel(),
Dialect::Fennel => Options::fennel(),
Dialect::Lfe => Options::lfe(),
Dialect::Islisp => Options::islisp(),
}
}
}
impl Default for Options {
fn default() -> Self {
Options::scheme()
}
}