Compare commits

...

2 Commits

Author SHA1 Message Date
Greg Shuflin
d084deac80 Start to correctly implmeent builtin functions 2021-10-31 03:13:51 -07:00
Greg Shuflin
87024b79ba Clippy 2021-10-31 02:44:33 -07:00
6 changed files with 38 additions and 23 deletions

View File

@ -2,8 +2,6 @@
## Testing ## Testing
* Get a test library for running many unit tests working
* Write a human-readable display of the AST
* Make an automatic (macro-based?) system for numbering compiler errors, this should be every type of error * Make an automatic (macro-based?) system for numbering compiler errors, this should be every type of error
## Symbols ## Symbols
@ -24,6 +22,10 @@
2. Once FQSNs are aware of function parameters, most of the Rc<String> things in eval.rs can go away 2. Once FQSNs are aware of function parameters, most of the Rc<String> things in eval.rs can go away
## Semantics
* Use annotations to indicate builtin functions
## Parser ## Parser
* I think I can restructure the parser to get rid of most instances of expect!, at least at the beginning of a rule * I think I can restructure the parser to get rid of most instances of expect!, at least at the beginning of a rule

View File

@ -28,7 +28,6 @@ pub enum Builtin {
GreaterThan, GreaterThan,
GreaterThanOrEqual, GreaterThanOrEqual,
Comparison, Comparison,
FieldAccess,
IOPrint, IOPrint,
IOPrintLn, IOPrintLn,
IOGetLine, IOGetLine,
@ -59,7 +58,6 @@ impl Builtin {
GreaterThan => ty!(Nat -> Nat -> Bool), GreaterThan => ty!(Nat -> Nat -> Bool),
GreaterThanOrEqual => ty!(Nat -> Nat -> Bool), GreaterThanOrEqual => ty!(Nat -> Nat -> Bool),
Comparison => ty!(Nat -> Nat -> Ordering), Comparison => ty!(Nat -> Nat -> Ordering),
FieldAccess => ty!(Unit),
IOPrint => ty!(Unit), IOPrint => ty!(Unit),
IOPrintLn => ty!(Unit), IOPrintLn => ty!(Unit),
IOGetLine => ty!(StringT), IOGetLine => ty!(StringT),
@ -120,7 +118,6 @@ impl FromStr for Builtin {
"==" => Equality, "==" => Equality,
"=" => Assignment, "=" => Assignment,
"<=>" => Comparison, "<=>" => Comparison,
"." => FieldAccess,
"print" => IOPrint, "print" => IOPrint,
"println" => IOPrintLn, "println" => IOPrintLn,
"getline" => IOGetLine, "getline" => IOGetLine,

View File

@ -394,14 +394,14 @@ impl Parser {
let tok = self.token_handler.peek(); let tok = self.token_handler.peek();
let kind = match tok.get_kind() { let kind = match tok.get_kind() {
AtSign => self.annotation().map(StatementKind::Declaration), AtSign => self.annotation().map(StatementKind::Declaration),
Keyword(Type) => self.type_declaration().map(|decl| StatementKind::Declaration(decl)), Keyword(Type) => self.type_declaration().map(StatementKind::Declaration),
Keyword(Func) => self.func_declaration().map(|func| StatementKind::Declaration(func)), Keyword(Func) => self.func_declaration().map(StatementKind::Declaration),
Keyword(Let) => self.binding_declaration().map(StatementKind::Declaration), Keyword(Let) => self.binding_declaration().map(StatementKind::Declaration),
Keyword(Interface) => self.interface_declaration().map(StatementKind::Declaration), Keyword(Interface) => self.interface_declaration().map(StatementKind::Declaration),
Keyword(Impl) => self.impl_declaration().map(StatementKind::Declaration), Keyword(Impl) => self.impl_declaration().map(StatementKind::Declaration),
Keyword(Import) => self.import_declaration().map(StatementKind::Import), Keyword(Import) => self.import_declaration().map(StatementKind::Import),
Keyword(Module) => self.module_declaration().map(StatementKind::Module), Keyword(Module) => self.module_declaration().map(StatementKind::Module),
_ => self.expression().map(|expr| StatementKind::Expression(expr)), _ => self.expression().map(StatementKind::Expression),
}?; }?;
let id = self.id_store.fresh(); let id = self.id_store.fresh();
Ok(Statement { kind, id, location: tok.location }) Ok(Statement { kind, id, location: tok.location })
@ -693,13 +693,8 @@ impl Parser {
#[recursive_descent_method] #[recursive_descent_method]
fn prefix_expr(&mut self) -> ParseResult<Expression> { fn prefix_expr(&mut self) -> ParseResult<Expression> {
loop { while let Semicolon | Newline = self.token_handler.peek_kind() {
match self.token_handler.peek_kind() { self.token_handler.next();
Semicolon | Newline => {
self.token_handler.next();
}
_ => break,
}
} }
match self.token_handler.peek_kind() { match self.token_handler.peek_kind() {

View File

@ -142,7 +142,7 @@ impl<'a, 'b> Reducer<'a, 'b> {
e => return Expression::ReductionError(format!("Bad symbol for NamedStruct: {:?}", e)), e => return Expression::ReductionError(format!("Bad symbol for NamedStruct: {:?}", e)),
}; };
let field_order = compute_field_orderings(&self.type_context, &type_id, tag).unwrap(); let field_order = compute_field_orderings(self.type_context, &type_id, tag).unwrap();
let mut field_map = HashMap::new(); let mut field_map = HashMap::new();
for (name, expr) in fields.iter() { for (name, expr) in fields.iter() {
@ -310,6 +310,7 @@ impl<'a, 'b> Reducer<'a, 'b> {
let def_id = symbol.def_id(); let def_id = symbol.def_id();
match symbol.spec() { match symbol.spec() {
Builtin(b) => Expression::Callable(Callable::Builtin(b)),
Func => Expression::Lookup(Lookup::Function(def_id.unwrap())), Func => Expression::Lookup(Lookup::Function(def_id.unwrap())),
GlobalBinding => Expression::Lookup(Lookup::GlobalVar(def_id.unwrap())), GlobalBinding => Expression::Lookup(Lookup::GlobalVar(def_id.unwrap())),
LocalVariable => Expression::Lookup(Lookup::LocalVar(def_id.unwrap())), LocalVariable => Expression::Lookup(Lookup::LocalVar(def_id.unwrap())),

View File

@ -12,6 +12,7 @@ use crate::{
Declaration, ItemId, ModuleSpecifier, Statement, StatementKind, TypeBody, TypeSingletonName, Variant, Declaration, ItemId, ModuleSpecifier, Statement, StatementKind, TypeBody, TypeSingletonName, Variant,
VariantKind, VariantKind,
}, },
builtin::Builtin,
tokenizing::Location, tokenizing::Location,
type_inference::{self, PendingType, TypeBuilder, TypeContext, TypeId, VariantBuilder}, type_inference::{self, PendingType, TypeBuilder, TypeContext, TypeId, VariantBuilder},
}; };
@ -42,7 +43,6 @@ impl Fqsn {
Fqsn { scopes: v } Fqsn { scopes: v }
} }
#[cfg(test)]
fn from_strs(strs: &[&str]) -> Fqsn { fn from_strs(strs: &[&str]) -> Fqsn {
let mut scopes = vec![]; let mut scopes = vec![];
for s in strs { for s in strs {
@ -152,7 +152,7 @@ pub struct SymbolTable {
impl SymbolTable { impl SymbolTable {
pub fn new() -> SymbolTable { pub fn new() -> SymbolTable {
SymbolTable { let mut table = SymbolTable {
def_id_store: IdStore::new(), def_id_store: IdStore::new(),
symbol_trie: SymbolTrie::new(), symbol_trie: SymbolTrie::new(),
fq_names: NameTable::new(), fq_names: NameTable::new(),
@ -161,7 +161,10 @@ impl SymbolTable {
fqsn_to_symbol: HashMap::new(), fqsn_to_symbol: HashMap::new(),
id_to_symbol: HashMap::new(), id_to_symbol: HashMap::new(),
def_to_symbol: HashMap::new(), def_to_symbol: HashMap::new(),
} };
table.populate_builtins();
table
} }
/// The main entry point into the symbol table. This will traverse the AST in several /// The main entry point into the symbol table. This will traverse the AST in several
@ -209,6 +212,24 @@ impl SymbolTable {
self.id_to_symbol.insert(*id, symbol.clone()); self.id_to_symbol.insert(*id, symbol.clone());
self.def_to_symbol.insert(def_id, symbol); self.def_to_symbol.insert(def_id, symbol);
} }
fn populate_single_builtin(&mut self, fqsn: Fqsn, builtin: Builtin) {
let def_id = self.def_id_store.fresh();
let spec = SymbolSpec::Builtin(builtin);
let symbol = Rc::new(Symbol { fully_qualified_name: fqsn.clone(), spec, def_id });
self.symbol_trie.insert(&fqsn);
self.fqsn_to_symbol.insert(fqsn, symbol.clone());
self.def_to_symbol.insert(def_id, symbol);
}
fn populate_builtins(&mut self) {
let fqsn = Fqsn::from_strs(&["println"]);
self.populate_single_builtin(fqsn, Builtin::IOPrintLn);
let fqsn = Fqsn::from_strs(&["print"]);
self.populate_single_builtin(fqsn, Builtin::IOPrint);
}
} }
struct SymbolTableRunner<'a> { struct SymbolTableRunner<'a> {
@ -258,6 +279,7 @@ impl fmt::Display for Symbol {
//function parameters (even though they are currently assigned). //function parameters (even though they are currently assigned).
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum SymbolSpec { pub enum SymbolSpec {
Builtin(Builtin),
Func, Func,
DataConstructor { tag: u32, type_id: TypeId }, DataConstructor { tag: u32, type_id: TypeId },
RecordConstructor { tag: u32, members: HashMap<Rc<String>, TypeId>, type_id: TypeId }, RecordConstructor { tag: u32, members: HashMap<Rc<String>, TypeId>, type_id: TypeId },
@ -270,6 +292,7 @@ impl fmt::Display for SymbolSpec {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::SymbolSpec::*; use self::SymbolSpec::*;
match self { match self {
Builtin(b) => write!(f, "Builtin: {:?}", b),
Func => write!(f, "Func"), Func => write!(f, "Func"),
DataConstructor { tag, type_id } => write!(f, "DataConstructor(tag: {}, type: {})", tag, type_id), DataConstructor { tag, type_id } => write!(f, "DataConstructor(tag: {}, type: {})", tag, type_id),
RecordConstructor { type_id, tag, .. } => RecordConstructor { type_id, tag, .. } =>

View File

@ -276,16 +276,13 @@ impl<'a, 'b> Evaluator<'a, 'b> {
let evaled_args = evaled_args?; let evaled_args = evaled_args?;
Ok(match (builtin, evaled_args.as_slice()) { Ok(match (builtin, evaled_args.as_slice()) {
(FieldAccess, /*&[Node::PrimObject { .. }]*/ _) => {
return Err("Field access unimplemented".into());
}
/* builtin functions */ /* builtin functions */
(IOPrint, &[ref anything]) => { (IOPrint, &[ref anything]) => {
print!("{}", anything.to_repl(self.type_context)); print!("{}", anything.to_repl(self.type_context));
Primitive::Tuple(vec![]) Primitive::Tuple(vec![])
} }
(IOPrintLn, &[ref anything]) => { (IOPrintLn, &[ref anything]) => {
print!("{}", anything.to_repl(self.type_context)); println!("{}", anything.to_repl(self.type_context));
Primitive::Tuple(vec![]) Primitive::Tuple(vec![])
} }
(IOGetLine, &[]) => { (IOGetLine, &[]) => {