Skip to content

Commit

Permalink
std::comptime: add tuple type support
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Jun 27, 2024
1 parent 1d9252a commit 3197ab2
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 3 deletions.
14 changes: 14 additions & 0 deletions std/comptime/type.jule
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ enum Kind {
UnsafePtr, // Unsafe raw pointer
Ref, // Smart pointer
Func, // Function
Tuple, // Tuple
}

// Returns compile-time type information.
Expand All @@ -39,6 +40,15 @@ enum Kind {
// will not executed at runtime.
// fn TypeOf(TYPE || EXPRESSION): comptimeTypeInfo

/* >>> Hint comptimeTypeInfos implementation.

// Private compile-time information wrapper for type infos.
// Supports iterable implementations.
// Using with built-in len function returns count of fields as constant expression.
struct comptimeTypeInfos {}

*/

/* >>> Hint comptimeTypeInfo implementation.

// Private compile-time type information wrapper.
Expand Down Expand Up @@ -79,6 +89,10 @@ impl comptimeTypeInfo {
// Supports only structure and enum types.
fn Fields(self): comptimeStructFields | comptimeEnumFields

// Returns comptime-type information datas for tuple types.
// Supports only tuple types.
fn Types(self): comptimeTypeInfos

// Reports whether type is public as constant expression.
// Supports only structures, enums, type enums, and traits.
fn Public(self): bool
Expand Down
13 changes: 13 additions & 0 deletions std/jule/sema/builtin.jule
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,11 @@ fn builtinCallerLen(mut &e: &Eval, mut &fc: &FnCallExpr, mut &d: &Data): &Data {
d.Constant = Const.NewI64(i64(len(dest.Kind.comptimeEnumFields().fields)))
d.Model = d.Constant
ret d
| dest.Kind.comptimeTypeInfos() != nil:
d.Kind = lenKind()
d.Constant = Const.NewI64(i64(len(dest.Kind.comptimeTypeInfos().types)))
d.Model = d.Constant
ret d
|:
e.pushErr(fc.Args[0].Token, LogMsg.InvalidExpr)
ret nil
Expand Down Expand Up @@ -873,6 +878,14 @@ fn builtinCallerStdComptimeRange(mut &e: &Eval, mut &fc: &FnCallExpr, mut &_: &D
},
},
}
| d.Kind.comptimeTypeInfos() != nil:
ret &Data{
Kind: &TypeKind{
Kind: &comptimeRange{
kind: d.Kind.comptimeTypeInfos(),
},
},
}
|:
e.pushErr(fc.Token, LogMsg.InvalidTypeForTypeOf, d.Kind.Str())
ret nil
Expand Down
84 changes: 83 additions & 1 deletion std/jule/sema/comptime.jule
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,60 @@ impl comptimeRangeKind for comptimeEnumFields {
}
}

// Compile-time type info range.
struct comptimeTypeInfos {
types: []&comptimeType
}

impl Kind for comptimeTypeInfos {
fn Str(self): str { ret "comptimeTypeInfos" }
fn Equal(&self, other: &TypeKind): bool { ret false }
}

impl comptimeRangeKind for comptimeTypeInfos {
fn ready(mut self, mut &keyA: &Var, mut &keyB: &Var) {
if keyA != nil {
keyA.Constant = true
keyA.Value = &Value{
Data: new(Data),
}
keyA.Value.Data.Constant = nil
keyA.Kind = &TypeSymbol{
Kind: &TypeKind{
Kind: buildPrimType(PrimKind.Int),
},
}
}
if keyB != nil {
keyB.Constant = true
keyB.Value = &Value{
Data: new(Data),
}
keyB.Kind = &TypeSymbol{
Kind: &TypeKind{
Kind: new(comptimeType),
},
}
}
}

fn step(mut self, i: int, mut &keyA: &Var, mut &keyB: &Var) {
if keyA != nil {
// Kind should be assigned by caller.
keyA.Value.Data.Constant = Const.NewI64(i64(i))
keyA.Value.Data.Model = keyA.Value.Data.Constant
}
if keyB != nil {
// Kind should be assigned by caller.
keyB.Kind.Kind.Kind = self.types[i]
}
}

fn len(self): int {
ret len(self.types)
}
}

// Compile-time type information data.
struct comptimeType {
base: &TypeKind
Expand Down Expand Up @@ -286,6 +340,8 @@ impl comptimeType {
item = enm.FindItem("Array")
| self.base.Fn() != nil:
item = enm.FindItem("Func")
| self.base.Tup() != nil:
item = enm.FindItem("Tuple")
| self.base.Prim() != nil:
let prim = self.base.Prim()
match {
Expand Down Expand Up @@ -508,6 +564,25 @@ impl comptimeType {
}
}

fn _Types(mut &self, mut &e: &Eval, mut &fc: &ast::FnCallExpr): &Data {
let mut tup = self.base.Tup()
if tup == nil {
e.pushErr(fc.Token, LogMsg.InvalidTypeForFn, self.base.Str(), "Types")
ret nil
}
let mut infos = &comptimeTypeInfos{
types: make([]&comptimeType, 0, len(tup.Types)),
}
for (_, mut t) in tup.Types {
infos.types = append(infos.types, e.s.meta.pushComptimeType(t))
}
ret &Data{
Kind: &TypeKind{
Kind: infos,
},
}
}

fn subIdent(mut &self, ident: str): &Data {
match ident {
| "Str":
Expand Down Expand Up @@ -559,6 +634,13 @@ impl comptimeType {
},
}
ret buildAsComptimeMethodData(method)
| "Types":
let mut method = &FnIns{
caller: fn(mut &e: &Eval, mut &fc: &ast::FnCallExpr, mut &_: &Data): &Data {
ret self._Types(e, fc)
},
}
ret buildAsComptimeMethodData(method)
| "Public":
let mut method = &FnIns{
caller: fn(mut &e: &Eval, mut &fc: &ast::FnCallExpr, mut &_: &Data): &Data {
Expand Down Expand Up @@ -624,7 +706,7 @@ fn findComptimePackage(mut &s: &Sema): &ImportInfo {
fn buildComptimeTypeInfoData(mut &s: &Sema, mut &t: &TypeKind): &Data {
ret &Data{
Kind: &TypeKind{
Kind: s.meta.pushComptimeType(t)
Kind: s.meta.pushComptimeType(t),
},
}
}
12 changes: 11 additions & 1 deletion std/jule/sema/type.jule
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,8 @@ impl TypeKind {

// Reports whether kind is comptime type.
fn comptime(mut self): bool {
ret self.comptimeType() != nil ||
ret self.comptimeTypeInfos() != nil ||
self.comptimeType() != nil ||
self.comptimeStructFields() != nil ||
self.comptimeStructField() != nil ||
self.comptimeEnumFields() != nil ||
Expand Down Expand Up @@ -421,6 +422,15 @@ impl TypeKind {
}
}

fn comptimeTypeInfos(mut self): &comptimeTypeInfos {
match type self.Kind {
| &comptimeTypeInfos:
ret (&comptimeTypeInfos)(self.Kind)
|:
ret nil
}
}

fn comptimeType(mut self): &comptimeType {
match type self.Kind {
| &comptimeType:
Expand Down
3 changes: 2 additions & 1 deletion std/jule/sema/type2.jule
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,8 @@ impl rangeChecker {
let mut range = self.d.Kind.comptimeRange()
match type range.kind {
| &comptimeStructFields
| &comptimeEnumFields:
| &comptimeEnumFields
| &comptimeTypeInfos:
self.checkComptime()
ret true
|:
Expand Down

0 comments on commit 3197ab2

Please sign in to comment.