mirror of
https://github.com/HigherOrderCO/Kind1.git
synced 2024-09-11 08:45:32 +03:00
fix: fixed char literals
This commit is contained in:
parent
bbe6c14cd6
commit
ba3aff95d6
@ -166,7 +166,9 @@ pub fn run_cli(config: Cli) {
|
||||
}
|
||||
Command::ToHVM { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), &mut |session| {
|
||||
driver::compile_book_to_hvm(session, &PathBuf::from(file.clone()))
|
||||
// TODO: Who sets the entrypoint?
|
||||
let book = driver::erase_book(session, &PathBuf::from(file.clone()), &["Main".to_string()])?;
|
||||
Some(driver::compile_book_to_hvm(book))
|
||||
})
|
||||
.map(|res| {
|
||||
println!("{}", res);
|
||||
@ -175,7 +177,9 @@ pub fn run_cli(config: Cli) {
|
||||
}
|
||||
Command::Run { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), &mut |session| {
|
||||
driver::compile_book_to_hvm(session, &PathBuf::from(file.clone()))
|
||||
let book = driver::desugar_book(session, &PathBuf::from(file.clone()))?;
|
||||
driver::check_main_entry(session, &book)?;
|
||||
Some(driver::compile_book_to_hvm(book))
|
||||
})
|
||||
.map(|res| {
|
||||
println!("{}", driver::execute_file(&res));
|
||||
@ -184,7 +188,9 @@ pub fn run_cli(config: Cli) {
|
||||
}
|
||||
Command::Eval { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), &mut |session| {
|
||||
driver::desugar_book(session, &PathBuf::from(file.clone()))
|
||||
let book = driver::desugar_book(session, &PathBuf::from(file.clone()))?;
|
||||
driver::check_main_entry(session, &book)?;
|
||||
Some(book)
|
||||
})
|
||||
.map(|res| {
|
||||
println!("{}", driver::eval_in_checker(&res));
|
||||
|
@ -75,7 +75,7 @@ fn test_eval() -> Result<(), Error> {
|
||||
let root = PathBuf::from(".");
|
||||
let mut session = Session::new(root, rx);
|
||||
|
||||
let check = driver::compile_book_to_hvm(&mut session, &PathBuf::from(path));
|
||||
let check = driver::erase_book(&mut session, &PathBuf::from(path), &["Main".to_string()]).map(driver::compile_book_to_hvm);
|
||||
|
||||
let diagnostics = tx.try_iter().collect::<Vec<_>>();
|
||||
let render = RenderConfig::ascii(2);
|
||||
|
@ -13,6 +13,7 @@ pub(crate) enum DriverError {
|
||||
UnboundVariable(Vec<Ident>, Vec<String>),
|
||||
MultiplePaths(QualifiedIdent, Vec<PathBuf>),
|
||||
DefinedMultipleTimes(QualifiedIdent, QualifiedIdent),
|
||||
ThereIsntAMain,
|
||||
}
|
||||
|
||||
impl Diagnostic for DriverError {
|
||||
@ -90,6 +91,15 @@ impl Diagnostic for DriverError {
|
||||
hints: vec![],
|
||||
positions: vec![],
|
||||
},
|
||||
|
||||
DriverError::ThereIsntAMain => DiagnosticFrame {
|
||||
code: 103,
|
||||
severity: Severity::Error,
|
||||
title: format!("Cannot find 'Main' function to run the file."),
|
||||
subtitles: vec![],
|
||||
hints: vec![],
|
||||
positions: vec![],
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use errors::DriverError;
|
||||
use kind_pass::{desugar, erasure, expand};
|
||||
use kind_report::report::FileCache;
|
||||
use kind_span::SyntaxCtxIndex;
|
||||
@ -82,8 +83,20 @@ pub fn check_erasure_book(session: &mut Session, path: &PathBuf) -> Option<desug
|
||||
Some(desugared_book)
|
||||
}
|
||||
|
||||
pub fn compile_book_to_hvm(session: &mut Session, path: &PathBuf) -> Option<backend::File> {
|
||||
erase_book(session, path, &["Main".to_string()]).map(kind_target_hvm::compile_book)
|
||||
pub fn compile_book_to_hvm(book: desugared::Book) -> backend::File {
|
||||
kind_target_hvm::compile_book(book)
|
||||
}
|
||||
|
||||
pub fn check_main_entry(session: &mut Session, book: &desugared::Book) -> Option<()> {
|
||||
if !book.entrs.contains_key("Main") {
|
||||
session
|
||||
.diagnostic_sender
|
||||
.send(Box::new(DriverError::ThereIsntAMain))
|
||||
.unwrap();
|
||||
None
|
||||
} else {
|
||||
Some(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute_file(file: &backend::File) -> Box<backend::Term> {
|
||||
|
@ -232,17 +232,20 @@ fn parse_and_store_book_by_path<'a>(
|
||||
}
|
||||
|
||||
fn unbound_variable(session: &mut Session, book: &Book, idents: &[Ident]) {
|
||||
let similar_names = book
|
||||
let mut similar_names = book
|
||||
.names
|
||||
.keys()
|
||||
.filter(|x| jaro(x, idents[0].to_string().as_str()).abs() > 0.8)
|
||||
.cloned()
|
||||
.collect();
|
||||
.map(|x| (jaro(x, idents[0].to_str()).abs(), x))
|
||||
.filter(|x| x.0 > 0.8)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
similar_names.sort_by(|x, y| x.0.total_cmp(&y.0));
|
||||
|
||||
session
|
||||
.diagnostic_sender
|
||||
.send(Box::new(DriverError::UnboundVariable(
|
||||
idents.to_vec(),
|
||||
similar_names,
|
||||
similar_names.iter().take(5).map(|x| x.1.clone()).collect(),
|
||||
)))
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -144,6 +144,27 @@ impl<'a> Lexer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lex_char(&mut self) -> Result<char, SyntaxError> {
|
||||
let start = self.span();
|
||||
if let Some(&x) = self.peekable.peek() {
|
||||
let chr_start = self.span();
|
||||
match x {
|
||||
'\\' => {
|
||||
self.next_char();
|
||||
match self.lex_escaped_char(chr_start) {
|
||||
Ok(x) => Ok(x),
|
||||
Err(t) => Err(t)
|
||||
}
|
||||
}
|
||||
x => {
|
||||
self.next_char();
|
||||
Ok(x)
|
||||
},
|
||||
}
|
||||
} else {
|
||||
Err(SyntaxError::UnfinishedChar(self.mk_range(start)))
|
||||
}
|
||||
}
|
||||
/// Lexes a string that starts with '"' and ends with the
|
||||
/// same char. each string item can contain a escaped char
|
||||
/// and if the esaped char is not well-formed then it will
|
||||
@ -174,6 +195,7 @@ impl<'a> Lexer<'a> {
|
||||
}
|
||||
x => string.push(x),
|
||||
}
|
||||
// FIXME: Not sure if it causes a bug!
|
||||
self.next_char();
|
||||
}
|
||||
|
||||
|
@ -187,6 +187,30 @@ impl<'a> Lexer<'a> {
|
||||
let str = self.accumulate_while(&is_valid_id);
|
||||
(Token::Help(str.to_string()), self.mk_range(start))
|
||||
}
|
||||
'\'' => {
|
||||
let start = self.span();
|
||||
self.next_char();
|
||||
let chr = match self.lex_char() {
|
||||
Ok(res) => res,
|
||||
Err(err) => return (Token::Error(err.into()), self.mk_range(start)),
|
||||
};
|
||||
match self.peekable.peek() {
|
||||
Some('\'') => self.single_token(Token::Char(chr), start),
|
||||
Some(c) => (
|
||||
Token::Error(Box::new(SyntaxError::UnexpectedChar(
|
||||
*c,
|
||||
self.mk_range(start),
|
||||
))),
|
||||
self.mk_range(start),
|
||||
),
|
||||
None => (
|
||||
Token::Error(Box::new(SyntaxError::UnfinishedChar(
|
||||
self.mk_range(start),
|
||||
))),
|
||||
self.mk_range(start),
|
||||
),
|
||||
}
|
||||
}
|
||||
'!' => {
|
||||
self.next_char();
|
||||
match self.peekable.peek() {
|
||||
|
@ -38,6 +38,13 @@ impl<'a> Parser<'a> {
|
||||
|| self.get().is_doc()
|
||||
}
|
||||
|
||||
pub fn is_safe_level_start(&self) -> bool {
|
||||
self.check_actual_id("type")
|
||||
|| self.check_actual_id("record")
|
||||
|| self.get().same_variant(&Token::Hash)
|
||||
|| self.get().is_doc()
|
||||
}
|
||||
|
||||
pub fn complement_binding_op(&self) -> Option<Token> {
|
||||
match self.get() {
|
||||
Token::LPar => Some(Token::RPar),
|
||||
@ -295,7 +302,7 @@ impl<'a> Parser<'a> {
|
||||
self.advance();
|
||||
self.errs.send(Box::new(err)).unwrap();
|
||||
self.failed = true;
|
||||
while (!self.is_top_level_start() || !self.is_linebreak())
|
||||
while (!self.is_safe_level_start() || !self.is_linebreak())
|
||||
&& !self.get().same_variant(&Token::Eof)
|
||||
{
|
||||
self.advance();
|
||||
|
@ -26,7 +26,7 @@ impl<'a> DesugarState<'a> {
|
||||
|
||||
fn attr_expects_a_value(&mut self, attr: &Attribute) {
|
||||
if !attr.value.is_some() {
|
||||
self.send_err(PassError::InvalidAttributeArgument(attr.range))
|
||||
self.send_err(PassError::AttributeExpectsAValue(attr.range))
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ impl<'a> DesugarState<'a> {
|
||||
Literal::Number(kind_tree::Number::U60(num)) => desugared::Expr::num60(range, *num),
|
||||
Literal::Number(kind_tree::Number::U120(num)) => desugared::Expr::num120(range, *num),
|
||||
Literal::String(string) => desugared::Expr::str(range, string.to_owned()),
|
||||
Literal::Char(_) => todo!(),
|
||||
Literal::Char(cht) => desugared::Expr::num60(range, *cht as u64),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ impl Visitor for UnboundCollector {
|
||||
let res = self
|
||||
.context_vars
|
||||
.iter()
|
||||
.find(|x| x.1 == argument.name.to_string());
|
||||
.find(|x| x.1 == argument.name.to_str());
|
||||
|
||||
if let Some(fst) = res {
|
||||
if self.emit_errs {
|
||||
@ -295,15 +295,15 @@ impl Visitor for UnboundCollector {
|
||||
self.visit_expr(val);
|
||||
let vars = self.context_vars.clone();
|
||||
self.visit_destruct(ident);
|
||||
self.context_vars = vars;
|
||||
self.visit_sttm(next);
|
||||
self.context_vars = vars;
|
||||
}
|
||||
SttmKind::Let(ident, val, next) => {
|
||||
self.visit_expr(val);
|
||||
let vars = self.context_vars.clone();
|
||||
self.visit_destruct(ident);
|
||||
self.context_vars = vars;
|
||||
self.visit_sttm(next);
|
||||
self.context_vars = vars;
|
||||
}
|
||||
SttmKind::Expr(expr, next) => {
|
||||
self.visit_expr(expr);
|
||||
|
@ -481,9 +481,7 @@ impl Report for Box<dyn Diagnostic> {
|
||||
)?;
|
||||
}
|
||||
|
||||
if !frame.hints.is_empty() {
|
||||
writeln!(fmt)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user