Skip to content

Commit

Permalink
std::comptime: initialize parameter support
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Jun 28, 2024
1 parent 5c04370 commit 9310681
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 0 deletions.
26 changes: 26 additions & 0 deletions std/comptime/type.jule
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ impl comptimeTypeInfo {
// Supports only structure and enum types.
fn Fields(self): comptimeStructFields | comptimeEnumFields

// Returns parameter information for function's parameters.
// Supports only function types.
fn Params(self): comptimeParams

// Returns comptime-type information datas for tuple types.
// Supports only tuple types.
fn Types(self): comptimeTypeInfos
Expand Down Expand Up @@ -168,4 +172,26 @@ impl comptimeStructField {
fn Name(self): str
}

*/

/* >>> Hint comptimeParams implementation.

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

*/

/* >>> Hint comptimeParam implementation.

// Private compile-time function parameter information wrapper.
struct comptimeParam {}

impl comptimeParam {
// Returns name of parameter.
// Returns as constant expression.
fn Name(self): str
}

*/
13 changes: 13 additions & 0 deletions std/jule/sema/builtin.jule
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,11 @@ fn builtinCallerLen(mut &e: &Eval, mut &fc: &FnCallExpr, mut &d: &Data): &Data {
d.Constant = Const.NewI64(i64(len(dest.Kind.comptimeTypeInfos().types)))
d.Model = d.Constant
ret d
| dest.Kind.comptimeParams() != nil:
d.Kind = lenKind()
d.Constant = Const.NewI64(i64(len(dest.Kind.comptimeParams().params)))
d.Model = d.Constant
ret d
|:
e.pushErr(fc.Args[0].Token, LogMsg.InvalidExpr)
ret nil
Expand Down Expand Up @@ -886,6 +891,14 @@ fn builtinCallerStdComptimeRange(mut &e: &Eval, mut &fc: &FnCallExpr, mut &_: &D
},
},
}
| d.Kind.comptimeParams() != nil:
ret &Data{
Kind: &TypeKind{
Kind: &comptimeRange{
kind: d.Kind.comptimeParams(),
},
},
}
|:
e.pushErr(fc.Token, LogMsg.InvalidTypeForTypeOf, d.Kind.Str())
ret nil
Expand Down
115 changes: 115 additions & 0 deletions std/jule/sema/comptime.jule
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,101 @@ impl comptimeRangeKind for comptimeEnumFields {
}
}

// Compile-time parameter for functions.
struct comptimeParam {
param: &ParamIns
}

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

impl comptimeParam {
fn _Name(&self): &Data {
let mut constant = Const.NewStr(self.param.Decl.Ident)
ret &Data{
Kind: &TypeKind{
Kind: buildPrimType(PrimKind.Str),
},
Constant: constant,
Model: constant,
}
}

fn _Type(mut &self, mut &e: &Eval): &Data {
ret buildComptimeTypeInfoData(e.s, self.param.Kind)
}

fn subIdent(mut &self, ident: str): &Data {
match ident {
| "Name":
let mut method = &FnIns{
caller: fn(mut &e: &Eval, mut &fc: &ast::FnCallExpr, mut &_: &Data): &Data {
ret self._Name()
},
}
ret buildAsComptimeMethodData(method)
|:
ret nil
}
}
}

// Compile-time parameters range for function.
struct comptimeParams {
params: []&ParamIns
}

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

impl comptimeRangeKind for comptimeParams {
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(comptimeParam),
},
}
}
}

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.comptimeParam().param = self.params[i]
}
}

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

// Compile-time type info range.
struct comptimeTypeInfos {
types: []&comptimeTypeInfo
Expand Down Expand Up @@ -612,6 +707,19 @@ impl comptimeTypeInfo {
ret buildComptimeTypeInfoData(e.s, f.Result)
}

fn _Params(mut &self, mut &e: &Eval, mut &fc: &ast::FnCallExpr): &Data {
let mut f = self.base.Fn()
if f == nil {
e.pushErr(fc.Token, LogMsg.InvalidTypeForFn, self.base.Str(), "Result")
ret nil
}
ret &Data{
Kind: &TypeKind{
Kind: &comptimeParams{params: f.Params},
}
}
}

fn subIdent(mut &self, ident: str): &Data {
match ident {
| "Str":
Expand Down Expand Up @@ -663,6 +771,13 @@ impl comptimeTypeInfo {
},
}
ret buildAsComptimeMethodData(method)
| "Params":
let mut method = &FnIns{
caller: fn(mut &e: &Eval, mut &fc: &ast::FnCallExpr, mut &_: &Data): &Data {
ret self._Params(e, fc)
},
}
ret buildAsComptimeMethodData(method)
| "Types":
let mut method = &FnIns{
caller: fn(mut &e: &Eval, mut &fc: &ast::FnCallExpr, mut &_: &Data): &Data {
Expand Down
7 changes: 7 additions & 0 deletions std/jule/sema/eval.jule
Original file line number Diff line number Diff line change
Expand Up @@ -2716,6 +2716,13 @@ impl Eval {
self.pushErr(si.Ident, LogMsg.ObjHaveNotIdent, d.Kind.Str(), si.Ident.Kind)
}
ret cd
| d.Kind.comptimeParam() != nil:
let mut comptimeP = d.Kind.comptimeParam()
let mut cd = comptimeP.subIdent(si.Ident.Kind)
if cd == nil {
self.pushErr(si.Ident, LogMsg.ObjHaveNotIdent, d.Kind.Str(), si.Ident.Kind)
}
ret cd
}

let mut kind = d.Kind
Expand Down
20 changes: 20 additions & 0 deletions std/jule/sema/type.jule
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ impl TypeKind {
self.comptimeStructField() != nil ||
self.comptimeEnumFields() != nil ||
self.comptimeEnumField() != nil ||
self.comptimeParams() != nil ||
self.comptimeParam() != nil ||
self.comptimeRange() != nil
}

Expand Down Expand Up @@ -413,6 +415,24 @@ impl TypeKind {
}
}

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

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

fn comptimeRange(mut self): &comptimeRange {
match type self.Kind {
| &comptimeRange:
Expand Down
1 change: 1 addition & 0 deletions std/jule/sema/type2.jule
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,7 @@ impl rangeChecker {
match type range.kind {
| &comptimeStructFields
| &comptimeEnumFields
| &comptimeParams
| &comptimeTypeInfos:
self.checkComptime()
ret true
Expand Down

0 comments on commit 9310681

Please sign in to comment.