Skip to content

Commit

Permalink
Allocate literals during hir lowering
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Jun 5, 2023
1 parent feeb29d commit 3cf78b6
Show file tree
Hide file tree
Showing 14 changed files with 366 additions and 368 deletions.
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

0 comments on commit 3cf78b6

Please sign in to comment.