Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allocate literals during hir lowering #542

Merged
merged 1 commit into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions crates/rune/src/ast/lit_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ impl LitStr {
&self,
ctx: ResolveContext<'a>,
) -> Result<Cow<'a, str>> {
self.resolve_string(ctx, ast::utils::WithTemplate(true))
self.resolve_inner(ctx, ast::utils::WithTemplate(true))
}

/// Resolve as a regular string.
pub(crate) fn resolve_string<'a>(&self, ctx: ResolveContext<'a>) -> Result<Cow<'a, str>> {
self.resolve_inner(ctx, ast::utils::WithTemplate(false))
}

/// Resolve the given string with the specified configuration.
pub(crate) fn resolve_string<'a>(
fn resolve_inner<'a>(
&self,
ctx: ResolveContext<'a>,
with_template: ast::utils::WithTemplate,
Expand Down Expand Up @@ -132,7 +137,7 @@ impl<'a> Resolve<'a> for LitStr {
type Output = Cow<'a, str>;

fn resolve(&self, ctx: ResolveContext<'a>) -> Result<Cow<'a, str>> {
self.resolve_string(ctx, ast::utils::WithTemplate(false))
self.resolve_string(ctx)
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/rune/src/ast/spanned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ where

impl<T> Spanned for &T
where
T: Spanned,
T: ?Sized + Spanned,
{
fn span(&self) -> Span {
Spanned::span(*self)
Expand All @@ -54,7 +54,7 @@ where

impl<T> Spanned for &mut T
where
T: Spanned,
T: ?Sized + Spanned,
{
fn span(&self) -> Span {
Spanned::span(*self)
Expand Down
5 changes: 0 additions & 5 deletions crates/rune/src/ast/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,6 @@ impl Number {
self.as_primitive(neg, num::ToPrimitive::to_u32)
}

/// Convert into a 64-bit signed number.
pub(crate) fn as_i64(&self, neg: bool) -> Result<i64, ParseErrorKind> {
self.as_primitive(neg, num::ToPrimitive::to_i64)
}

/// Convert into usize.
pub(crate) fn as_usize(&self, neg: bool) -> Result<usize, ParseErrorKind> {
self.as_primitive(neg, num::ToPrimitive::to_usize)
Expand Down
2 changes: 0 additions & 2 deletions crates/rune/src/compile/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,6 @@ pub(crate) enum IrErrorKind {
FnNotFound,
#[error("Argument count mismatch, got {actual} but expected {expected}")]
ArgumentCountMismatch { actual: usize, expected: usize },
#[error("Value `{value}` is outside of the supported integer range")]
NotInteger { value: num::BigInt },
}

/// The kind of a hir error.
Expand Down
11 changes: 3 additions & 8 deletions crates/rune/src/compile/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ pub struct IrBranches {
/// The condition for a branch.
#[derive(Debug, Clone, Spanned)]
pub enum IrCondition {
/// A simple conditiona ir expression.
/// A simple conditional ir expression.
Ir(Ir),
/// A pattern match.
Let(IrLet),
Expand Down Expand Up @@ -558,12 +558,7 @@ impl IrAssignOp {
}

/// Perform the given assign operation.
fn assign_int<S>(
self,
spanned: S,
target: &mut num::BigInt,
operand: num::BigInt,
) -> compile::Result<()>
fn assign_int<S>(self, spanned: S, target: &mut i64, operand: i64) -> compile::Result<()>
where
S: Copy + Spanned,
{
Expand All @@ -579,7 +574,7 @@ impl IrAssignOp {
}
IrAssignOp::Div => {
*target = target
.checked_div(&operand)
.checked_div(operand)
.ok_or("division by zero")
.with_span(spanned)?;
}
Expand Down
65 changes: 14 additions & 51 deletions crates/rune/src/compile/ir/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub(crate) fn expr(hir: &hir::Expr<'_>, c: &mut IrCompiler<'_>) -> compile::Resu
hir::ExprKind::Call(hir) => ir::Ir::new(span, expr_call(span, c, hir)?),
hir::ExprKind::If(hir) => ir::Ir::new(span, expr_if(span, c, hir)?),
hir::ExprKind::Loop(hir) => ir::Ir::new(span, expr_loop(span, c, hir)?),
hir::ExprKind::Lit(hir) => lit(hir, c)?,
hir::ExprKind::Lit(hir) => lit(span, c, hir)?,
hir::ExprKind::Block(hir) => expr_block(span, c, hir)?,
hir::ExprKind::Path(hir) => path(hir, c)?,
hir::ExprKind::FieldAccess(..) => ir::Ir::new(span, c.ir_target(hir)?),
Expand All @@ -100,20 +100,8 @@ pub(crate) fn expr(hir: &hir::Expr<'_>, c: &mut IrCompiler<'_>) -> compile::Resu
let ir_template = builtin_template(template, c)?;
ir::Ir::new(hir.span(), ir_template)
}
hir::MacroCall::File(file) => {
let s = c.resolve(&file.value)?;
ir::Ir::new(file.span, IrValue::String(Shared::new(s.into_owned())))
}
hir::MacroCall::Line(line) => {
let n = c.resolve(&line.value)?;

let const_value = match n {
ast::Number::Integer(n) => IrValue::Integer(n),
ast::Number::Float(n) => IrValue::Float(n),
};

ir::Ir::new(line.span, const_value)
}
hir::MacroCall::File(file) => lit(span, c, file.value)?,
hir::MacroCall::Line(line) => lit(span, c, line.value)?,
_ => {
return Err(compile::Error::msg(hir, "unsupported builtin macro"));
}
Expand Down Expand Up @@ -227,38 +215,18 @@ fn expr_binary(
}

#[instrument]
fn lit(hir: &ast::Lit, c: &mut IrCompiler<'_>) -> compile::Result<ir::Ir> {
let span = hir.span();

fn lit(span: Span, c: &mut IrCompiler<'_>, hir: hir::Lit<'_>) -> compile::Result<ir::Ir> {
Ok(match hir {
ast::Lit::Bool(b) => ir::Ir::new(span, IrValue::Bool(b.value)),
ast::Lit::Str(s) => {
let s = c.resolve(s)?;
ir::Ir::new(span, IrValue::String(Shared::new(s.into_owned())))
}
ast::Lit::Number(n) => {
let n = c.resolve(n)?;

let const_value = match n {
ast::Number::Integer(n) => IrValue::Integer(n),
ast::Number::Float(n) => IrValue::Float(n),
};

ir::Ir::new(span, const_value)
}
ast::Lit::Byte(lit) => {
let b = c.resolve(lit)?;
ir::Ir::new(span, IrValue::Byte(b))
}
ast::Lit::ByteStr(lit) => {
let byte_str = c.resolve(lit)?;
let value = IrValue::Bytes(Shared::new(Bytes::from_vec(byte_str.into_owned())));
hir::Lit::Bool(boolean) => ir::Ir::new(span, IrValue::Bool(boolean)),
hir::Lit::Str(string) => ir::Ir::new(span, IrValue::String(Shared::new(string.to_owned()))),
hir::Lit::Integer(n) => ir::Ir::new(span, IrValue::Integer(n)),
hir::Lit::Float(n) => ir::Ir::new(span, IrValue::Float(n)),
hir::Lit::Byte(b) => ir::Ir::new(span, IrValue::Byte(b)),
hir::Lit::ByteStr(byte_str) => {
let value = IrValue::Bytes(Shared::new(Bytes::from_vec(byte_str.to_vec())));
ir::Ir::new(span, value)
}
ast::Lit::Char(lit) => {
let c = c.resolve(lit)?;
ir::Ir::new(span, IrValue::Char(c))
}
hir::Lit::Char(c) => ir::Ir::new(span, IrValue::Char(c)),
})
}

Expand Down Expand Up @@ -400,13 +368,8 @@ fn builtin_template(
let mut components = Vec::new();

for e in template.exprs {
if let hir::ExprKind::Lit(ast::Lit::Str(s)) = e.kind {
let s = s.resolve_template_string(resolve_context!(c.q))?;

components.push(ir::IrTemplateComponent::String(
s.into_owned().into_boxed_str(),
));

if let hir::ExprKind::Lit(hir::Lit::Str(s)) = e.kind {
components.push(ir::IrTemplateComponent::String(s.into()));
continue;
}

Expand Down
2 changes: 1 addition & 1 deletion crates/rune/src/compile/ir/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ fn eval_ir_binary(
}
ir::IrBinaryOp::Div => {
let number = a
.checked_div(&b)
.checked_div(b)
.ok_or_else(|| compile::Error::msg(span, "division by zero"))?;
return Ok(IrValue::Integer(number));
}
Expand Down
24 changes: 5 additions & 19 deletions crates/rune/src/compile/ir/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::no_std::collections::HashMap;
use crate::no_std::prelude::*;

use crate::ast::Spanned;
use crate::compile::{self, IrErrorKind, WithSpan};
use crate::compile::{self, WithSpan};
use crate::runtime as rt;
use crate::runtime::{Bytes, ConstValue, Shared, TypeInfo};

Expand All @@ -18,7 +18,7 @@ pub enum IrValue {
/// A boolean constant value.
Bool(bool),
/// An integer constant.
Integer(num::BigInt),
Integer(i64),
/// An float constant.
Float(f64),
/// A string constant designated by its slot.
Expand Down Expand Up @@ -47,7 +47,7 @@ impl IrValue {
/// Try to coerce into an integer of the specified type.
pub fn into_integer<T>(self) -> Option<T>
where
T: TryFrom<num::BigInt>,
T: TryFrom<i64>,
{
match self {
Self::Integer(n) => T::try_from(n).ok(),
Expand All @@ -62,7 +62,7 @@ impl IrValue {
ConstValue::Byte(b) => Self::Byte(*b),
ConstValue::Char(c) => Self::Char(*c),
ConstValue::Bool(b) => Self::Bool(*b),
ConstValue::Integer(n) => Self::Integer((*n).into()),
ConstValue::Integer(n) => Self::Integer(*n),
ConstValue::Float(n) => Self::Float(*n),
ConstValue::String(s) => Self::String(Shared::new(s.clone())),
ConstValue::StaticString(s) => Self::String(Shared::new((***s).to_owned())),
Expand Down Expand Up @@ -105,26 +105,12 @@ impl IrValue {
where
S: Copy + Spanned,
{
use num::ToPrimitive as _;

Ok(match self {
IrValue::Unit => ConstValue::Unit,
IrValue::Byte(b) => ConstValue::Byte(b),
IrValue::Char(c) => ConstValue::Char(c),
IrValue::Bool(b) => ConstValue::Bool(b),
IrValue::Integer(n) => {
let n = match n.clone().to_i64() {
Some(n) => n,
None => {
return Err(compile::Error::new(
spanned,
IrErrorKind::NotInteger { value: n },
))
}
};

ConstValue::Integer(n)
}
IrValue::Integer(n) => ConstValue::Integer(n),
IrValue::Float(f) => ConstValue::Float(f),
IrValue::String(s) => {
let s = s.take().with_span(spanned)?;
Expand Down
Loading