use crate::ast::Literal;
use crate::ir::hir::BuiltinIntrinsic;
use crate::ir::identity::{FnId, FnKey};
use crate::nan_value::{NanIntExt, NanValue};
use crate::vm::opcode::{
BUFFER_APPEND_SEP_UNLESS_FIRST, BUFFER_APPEND_STR, BUFFER_FINALIZE, BUFFER_NEW, INT_DIV_EUCLID,
INT_MOD_EUCLID,
};
use std::str::FromStr;
use super::{CompileError, FnCompiler};
pub(super) fn buffer_intrinsic_opcode(intrinsic: BuiltinIntrinsic) -> Option<(u8, usize)> {
match intrinsic {
BuiltinIntrinsic::BufNew => Some((BUFFER_NEW, 1)),
BuiltinIntrinsic::BufAppend => Some((BUFFER_APPEND_STR, 2)),
BuiltinIntrinsic::BufAppendSepUnlessFirst => Some((BUFFER_APPEND_SEP_UNLESS_FIRST, 2)),
BuiltinIntrinsic::BufFinalize => Some((BUFFER_FINALIZE, 1)),
BuiltinIntrinsic::IntDivEuclid => Some((INT_DIV_EUCLID, 2)),
BuiltinIntrinsic::IntModEuclid => Some((INT_MOD_EUCLID, 2)),
BuiltinIntrinsic::ToStr => None,
}
}
impl FnCompiler<'_> {
pub(super) fn resolve_type_id(&self, name: &str) -> Option<u32> {
self.arena.find_type_id(name)
}
pub(super) fn resolve_fn_id_by_name(&self, name: &str) -> Option<u32> {
self.module_scope()
.get(name)
.copied()
.or_else(|| self.code_store.find(name))
}
pub(super) fn canonical_fn_name(&self, fn_id: FnId) -> Result<String, CompileError> {
let entry = self.symbol_table.fn_entry(fn_id);
Ok(canonical_name_from_key(&entry.key))
}
pub(super) fn canonical_type_name(
&self,
type_id: crate::ir::identity::TypeId,
) -> Result<String, CompileError> {
let entry = self.symbol_table.type_entry(type_id);
let key = &entry.key;
Ok(match key.scope_str() {
Some(scope) => format!("{}.{}", scope, key.name),
None => key.name.clone(),
})
}
pub(super) fn nan_literal(&mut self, lit: &Literal) -> NanValue {
match lit {
Literal::Int(i) => NanValue::new_int(*i, self.arena),
Literal::BigInt(s) => NanValue::from_aver_int(
aver_rt::AverInt::from_str(s).expect("lexer-validated big integer literal"),
self.arena,
),
Literal::Float(f) => NanValue::new_float(*f),
Literal::Bool(true) => NanValue::TRUE,
Literal::Bool(false) => NanValue::FALSE,
Literal::Unit => NanValue::UNIT,
Literal::Str(s) => NanValue::new_string_value(s, self.arena),
}
}
}
fn canonical_name_from_key(key: &FnKey) -> String {
key.canonical()
}