Skip to content

Commit 3a86ee7

Browse files
committed
add rough draft of class methods + refactor descriptors
1 parent 9c5113b commit 3a86ee7

4 files changed

Lines changed: 49 additions & 19 deletions

File tree

programs/testclassmethod.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@classmethod
2+
def a(x): assert x is int
3+
4+
a.__get__(5, int)()
5+
a.__get__(5, None)()
6+
a.__get__(None, int)()

python-semantics-common.k

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ module PYTHON-SEMANTICS-COMMON
7171
| "name" "(" Expression ")"
7272
| "codeObject" "(" Id "," Parameters "," K "," Bool ")"
7373
| "class" "(" Arguments "," Expression ")" [strict]
74+
| describe(Expression, Expression, Expression, String) [strict(1 2 3)]
75+
| doDescribe(Expression, Expression, Expression, String) [strict(1 2 3)]
7476

7577
syntax K ::= "iterate" "(" Expression "," K ")" [strict(1)]
7678

@@ -235,8 +237,12 @@ module PYTHON-SEMANTICS-COMMON
235237
rule hasbase(list(ListItem(N) L), Base) => or(hasbase(ref(N), Base),hasbase(list(L), Base))
236238
rule hasbase(list(.List), Base) => false
237239
238-
rule <k> invokeBuiltin(obj("get_ref",_), ListItem(obj(_, <oattrs>... "__get__" |-> S ...</oattrs>)) ListItem(O) ListItem(_), .) => getref(O, S) ...</k>
239-
rule <k> invokeBuiltin(obj("get_attr",_), ListItem(obj(_, <oattrs>... "__get__" |-> S ...</oattrs>)) ListItem(O) ListItem(_), .) => getattr(O, S) ...</k>
240+
rule invokeBuiltin(obj("get_ref",_), ListItem(Self) ListItem(Instance) ListItem(Owner), .) => describe(Self, Instance, Owner, "get_ref")
241+
rule invokeBuiltin(obj("get_attr",_), ListItem(Self) ListItem(Instance) ListItem(Owner), .) => describe(Self, Instance, Owner, "get_attr")
242+
rule doDescribe(Self, .Obj, _, "get_ref") => Self
243+
rule doDescribe(Self, .Obj, _, "get_attr") => Self
244+
rule doDescribe(Self, O:Object, _, "get_ref") => getref(O, getattr(Self, "__get__"))
245+
rule doDescribe(Self, O:Object, _, "get_attr") => getattr(O, getattr(Self, "__get__"))
240246
241247
rule <k> ref(S:String) => ref(N:Int) ...</k>
242248
<symbols>... S |-> N ...</symbols>
@@ -299,4 +305,10 @@ module PYTHON-SEMANTICS-COMMON
299305
rule (. => X:Id, .Expressions := ref(B)) ~> setArgs((X |-> B => .) _)
300306
rule setArgs(.) => .
301307
308+
rule <k> describe(Self, Instance, Owner, S) => doDescribe(Self, Instance, gettype(Instance), S) ...</k>
309+
<symbols>... "None" |-> NoneId ...</symbols> when id(Owner) ==Int NoneId
310+
311+
rule <k> describe(Self, Instance, Owner, S) => doDescribe(Self, .Obj, Owner, S) ...</k>
312+
<symbols>... "None" |-> NoneId ...</symbols> when id(Owner) =/=Int NoneId
313+
302314
endmodule

python-semantics-dunder-builtin.k

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ module PYTHON-SEMANTICS-DUNDER-BUILTIN
3737
object "bool"("type",ListItem("int"),
3838
"__new__" |-> def "new_bool" (1, 2, false)
3939
,.) ~>
40+
object "classmethod"("type", ListItem("object"),
41+
"__get__" |-> def "get_classmethod"(1, 2, true)
42+
"__init__" |-> def "init_classmethod"(1, 1, true)
43+
"__new__" |-> def "new_classmethod"(2, 2, false)
44+
,.) ~>
4045
object "complex"("type",ListItem("object"),.,.) ~>
4146
object "dict"("type",ListItem("object"),
4247
"keys" |-> def "keys_dict" (0, 0, true)

python-semantics-methods.k

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,48 @@ require "python-semantics-common.k"
33
module PYTHON-SEMANTICS-METHODS
44
imports PYTHON-SEMANTICS-COMMON
55

6-
syntax ObjRef ::= "method" "(" Expression "," Expression "," Expression ")" [strict]
6+
syntax ObjRef ::= "method" "(" Expression "," Expression ")" [strict]
77

8-
rule <k> invokeBuiltin(obj("get_builtin_method",_), ListItem(Self:Object) ListItem(Instance:Object) ListItem(Owner:Object), .) => method(Self, Instance, Owner) ...</k>
9-
rule <k> invokeBuiltin(obj("get_function",_), ListItem(Self:Object) ListItem(Instance:Object) ListItem(Owner:Object), .) => method(Self, Instance, Owner) ...</k>
8+
rule invokeBuiltin(obj("get_builtin_method",_), ListItem(Self:Object) ListItem(Instance:Object) ListItem(Owner:Object), .) => describe(Self, Instance, Owner, "get_function")
9+
rule invokeBuiltin(obj("get_function",_), ListItem(Self:Object) ListItem(Instance:Object) ListItem(Owner:Object), .) => describe(Self, Instance, Owner, "get_function")
10+
rule doDescribe(Self, .Obj, O, "get_function") => O
11+
rule doDescribe(Self, O:Object, _, "get_function") => method(Self, O)
1012

1113
syntax K ::= "triple" "(" K "," K "," K ")"
1214

13-
rule <k> method(obj(FuncId,_), obj(SelfId,_), obj(OwnerId:Nat,_)) => ref(N:Nat) ...</k>
14-
<symbols>... "method" |-> N2:Nat "None" |-> NoneId:Nat...</symbols>
15+
rule <k> method(obj(FuncId,_), obj(SelfId,_)) => ref(N:Nat) ...</k>
16+
<symbols>... "method" |-> N2:Nat ...</symbols>
1517
<literals> M (. => triple(FuncId, SelfId, N2) |-> N) </literals>
1618
<nextLoc>N => N +Int 1</nextLoc>
1719
(. =>
1820
<object>...
1921
<id>N</id>
2022
<oattrs> "__class__" |-> N2 "__func__" |-> FuncId "__self__" |-> SelfId </oattrs>
21-
...</object>) when (SelfId =/=Int NoneId orBool OwnerId ==Int NoneId) andBool notBool(triple(FuncId, SelfId, N2) in keys M)
23+
...</object>) when notBool(triple(FuncId, SelfId, N2) in keys M)
2224

23-
rule <k> method(obj(FuncId,_), obj(SelfId,_), obj(OwnerId,_)) => ref(N) ...</k>
25+
rule <k> method(obj(FuncId,_), obj(SelfId,_))) => ref(N) ...</k>
2426
<literals>... triple(FuncId, SelfId, N2) |-> N ...</literals>
25-
<symbols>... "method" |-> N2:Nat "None" |-> NoneId:Nat...</symbols> when (SelfId =/=Int NoneId orBool OwnerId ==Int NoneId)
26-
27-
rule <k> method(O:Object, obj(NoneId,_), obj(OwnerId,_)) => O ...</k>
28-
<symbols>... "None" |-> NoneId ...</symbols> when OwnerId =/=Int NoneId
27+
<symbols>... "method" |-> N2:Nat ...</symbols>
2928

3029
//can't use descriptors because method descriptors use it
31-
rule <k> obj(N:Nat,ObjState:Bag) (Args:K) => (getmember(obj(N,ObjState), "__call__", false, false, false) (obj(N,ObjState), Args)) -> (raiseInternal("TypeError", "object is not callable")) ...</k>
30+
rule obj(N:Nat,ObjState:Bag) (Args:K) => (getmember(obj(N,ObjState), "__call__", false, false, false) (obj(N,ObjState), Args)) -> (raiseInternal("TypeError", "object is not callable"))
3231

3332
rule <k> invokeBuiltin(obj("call_method",_), ListItem(obj(N, <oattrs>... "__func__" |-> FuncId:Builtin "__self__" |-> SelfId:Builtin ...</oattrs>)) L:List, M:Map) => doCall(ref(FuncId), ListItem(ref(SelfId)) L, M) ...</k>
3433
<symbols>... "None" |-> NoneId:Nat ...</symbols>
3534

36-
rule <k> doCall((O:Object => .), _, _) ~> (. => O (.Arguments)) ...</k>
37-
rule <k> doCall(., _ (ListItem(K:K) => .), .) ~> _:Object (Args:K => (K , Args)) ...</k>
38-
rule <k> doCall(., _, _ (S:String |-> K => .)) ~> _:Object (Args:K => (String2Id(S) = K, Args)) ...</k>
39-
rule <k> doCall(., ., .) => . ...</k>
35+
rule doCall((O:Object => .), _, _) ~> (. => O (.Arguments))
36+
rule doCall(., _ (ListItem(K:K) => .), .) ~> _:Object (Args:K => (K , Args))
37+
rule doCall(., _, _ (S:String |-> K => .)) ~> _:Object (Args:K => (String2Id(S) = K, Args))
38+
rule doCall(., ., .) => .
39+
40+
rule invokeBuiltin(obj("call_builtin_function",_), ListItem(obj(B:Builtin,<oattrs>... "__call__" |-> S:String ...</oattrs>)) L, M) => doCall(ref(S), L, M)
41+
42+
rule <k> invokeBuiltin(obj("new_classmethod",_), ListItem(Class) ListItem(Method), .) => newHelper(Class, ref("classmethod"), .) ~> mutable("__func__" |-> None, Class) ...</k>
43+
<symbols>... "None" |-> None ...</symbols>
44+
45+
rule invokeBuiltin(obj("init_classmethod",_), ListItem(Self) ListItem(Method), .) => setref(id(Self), "__func__", Method) ~> ref("None")
4046

41-
rule <k> invokeBuiltin(obj("call_builtin_function",_), ListItem(obj(B:Builtin,<oattrs>... "__call__" |-> S:String ...</oattrs>)) L, M) => doCall(ref(S), L, M) ...</k>
47+
rule invokeBuiltin(obj("get_classmethod",_), ListItem(Self) ListItem(Instance) ListItem(Owner), .) => describe(Self, Instance, Owner, "get_classmethod")
48+
rule doDescribe(Self, _, Owner, "get_classmethod") => method(getref(Self, "__func__"), Owner)
4249

4350
endmodule

0 commit comments

Comments
 (0)