Skip to content

Commit

Permalink
Implement __IMPLIED_TYPE__ (#368)
Browse files Browse the repository at this point in the history
It turns out this kinda sucks. it doesn't work with ::, so we don't even
really need to care about its value. I threw in support for constant
eval but that's inconsistent on our end cause type_hint doesn't always
play. I figure it's good to at least have something, and issues can get
sorted out as we go.

It is also seemingly massively annoying to eval in like, an istype(), 
since it has special case behavior there. I just kinda left it sit 
since I'm pretty sure it'd be a massive change to support and it like 
does not matter.
  • Loading branch information
LemonInTheDark authored Oct 17, 2023
1 parent a50249e commit e5dbc57
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 1 deletion.
8 changes: 7 additions & 1 deletion crates/dm-langserver/src/find_references.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,6 @@ impl<'o> WalkProc<'o> {
StaticType::None
}
},

Term::__TYPE__ => {
self.tab.use_symbol(self.ty.id, location);
StaticType::None
Expand All @@ -558,6 +557,13 @@ impl<'o> WalkProc<'o> {
}
StaticType::None
}
Term::__IMPLIED_TYPE__ => {
let Some(implied_type) = type_hint else {
return StaticType::None
};
self.tab.use_symbol(implied_type.id, location);
StaticType::Type(implied_type)
},
}
}

Expand Down
13 changes: 13 additions & 0 deletions crates/dreamchecker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1898,6 +1898,19 @@ impl<'o, 's> AnalyzeProc<'o, 's> {
// Can't fuckin do it bros
Analysis::empty()
},
Term::__IMPLIED_TYPE__ => {
let Some(implied_type) = type_hint else {
return Analysis::empty()
};
let pop = dm::constants::Pop::from(implied_type.path.split('/').skip(1).map(ToOwned::to_owned).collect::<Vec<_>>().into_boxed_slice());
Analysis {
static_ty: StaticType::None,
aset: assumption_set![Assumption::IsPath(true, self.ty)],
value: Some(Constant::Prefab(Box::new(pop))),
fix_hint: None,
is_impure: None,
}
},
}
}

Expand Down
6 changes: 6 additions & 0 deletions crates/dreammaker/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,7 @@ impl From<Term> for Expression {
}

/// The structure of a term, the basic building block of the AST.
#[allow(non_camel_case_types)]
#[derive(Clone, PartialEq, Debug, GetSize)]
pub enum Term {
// Terms with no recursive contents ---------------------------------------
Expand All @@ -875,6 +876,11 @@ pub enum Term {
__PROC__,
/// A reference to the current proc/scope's type
__TYPE__,
/// If rhs of an assignment op, this is a reference to the lhs var's type
/// If we're used as the second arg of an istype then it's the implied type of the first arg
/// Second case takes precedence over the first, but we don't properly implement because it would be impossible to
/// Tell. You can't DO anything to the __IMPLIED_TYPE__ so we don't really need to care about it
__IMPLIED_TYPE__,

// Non-function calls with recursive contents -----------------------------
/// An expression contained in a term.
Expand Down
7 changes: 7 additions & 0 deletions crates/dreammaker/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,13 @@ impl<'a> ConstantFolder<'a> {
return Err(self.error("No type context".to_owned()))
}
},
Term::__IMPLIED_TYPE__ => {
if let Some(lhs_type) = type_hint {
Constant::Prefab(Box::new(Pop::from(lhs_type.clone())))
} else {
return Err(self.error("No type hint".to_owned()))
}
},
_ => return Err(self.error("non-constant expression".to_owned())),
})
}
Expand Down
6 changes: 6 additions & 0 deletions crates/dreammaker/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2085,6 +2085,12 @@ impl<'ctx, 'an, 'inp> Parser<'ctx, 'an, 'inp> {
Term::__TYPE__
},

// term :: __IMPLIED_TYPE__
Token::Ident(ref i, _) if i == "__IMPLIED_TYPE__" => {
// We cannot replace with the typepath yet, so we'll hand back a term we can parse later
Term::__IMPLIED_TYPE__
},

// term :: ident arglist | ident
Token::Ident(i, _) => {
let first_token = self.updated_location();
Expand Down

0 comments on commit e5dbc57

Please sign in to comment.