diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-28 23:37:35 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-29 19:20:34 +0200 |
commit | 41982de3beb59b26c57f2627a7d74f223831e75f (patch) | |
tree | c6e23545df7da1723fb34302e39c2154b9f8cd1e /crates | |
parent | f03f4dfc06ef0a2022b8cb35eced694ca07a063d (diff) | |
download | rebel-41982de3beb59b26c57f2627a7d74f223831e75f.tar rebel-41982de3beb59b26c57f2627a7d74f223831e75f.zip |
rebel-lang: typing: implement turning an AST Type into a runtime Type
Diffstat (limited to 'crates')
-rw-r--r-- | crates/rebel-lang/src/typing.rs | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/crates/rebel-lang/src/typing.rs b/crates/rebel-lang/src/typing.rs index fc3009a..2af8d33 100644 --- a/crates/rebel-lang/src/typing.rs +++ b/crates/rebel-lang/src/typing.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, fmt::Display}; use enum_kinds::EnumKind; -use rebel_parse::ast::{self, expr}; +use rebel_parse::ast::{self, expr, typ}; use crate::{func::FuncType, scope::Context}; @@ -79,6 +79,50 @@ impl Type { }) } + pub fn ast_type(ctx: &Context, expr: &typ::Type<'_>) -> Result<Type> { + use typ::Type::*; + + Ok(match expr { + Paren(subexpr) => Self::ast_type(ctx, subexpr)?, + Path(path) => Self::path_type(ctx, path)?, + Literal(lit) => Self::literal_type(ctx, lit)?, + }) + } + + fn path_type(ctx: &Context, path: &ast::Path<'_>) -> Result<Type> { + use Type::*; + + if path.components == [ast::Ident { name: "_" }] { + return Ok(Free); + } + + ctx.types.lookup(&path.components).cloned().ok_or(TypeError) + } + + fn literal_type(ctx: &Context, lit: &typ::Literal<'_>) -> Result<Type> { + use typ::Literal; + use Type::*; + + Ok(match lit { + Literal::Unit => Unit, + Literal::Tuple(elems) => Tuple( + elems + .iter() + .map(|elem| Self::ast_type(ctx, elem)) + .collect::<Result<_>>()?, + ), + Literal::Array(typ, len) => Array(Box::new(Self::ast_type(ctx, typ)?), (*len).into()), + Literal::Struct(entries) => Struct( + entries + .iter() + .map(|typ::StructField { name, typ }| { + Ok(((*name).to_owned(), Self::ast_type(ctx, typ)?)) + }) + .collect::<Result<_>>()?, + ), + }) + } + pub fn ast_stmt_type(ctx: &Context, stmt: &ast::BodyStmt<'_>) -> Result<Type> { match stmt { ast::BodyStmt::Assign { dest: _, expr } => { @@ -417,6 +461,16 @@ impl ArrayLen { } } +impl From<typ::ArrayLen> for ArrayLen { + fn from(value: typ::ArrayLen) -> Self { + match value { + typ::ArrayLen::Free => ArrayLen::Free, + typ::ArrayLen::Fixed(len) => ArrayLen::Fixed(len), + typ::ArrayLen::Dynamic => ArrayLen::Dynamic, + } + } +} + impl Display for ArrayLen { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { |