1 ////////////////////////////////////////////////////////////////////////////////
5 // Copyright 2011 Zach Wegner
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 ////////////////////////////////////////////////////////////////////////////////
21 #define __STDC_FORMAT_MACROS
37 __attribute((noreturn
)) void error(const char *msg
, ...) {
54 typedef int64_t int_t
;
56 typedef std::pair
<node
*, node
*> node_pair
;
57 typedef std::map
<int_t
, node_pair
> node_dict
;
58 typedef std::map
<int_t
, node
*> node_set
;
59 typedef std::vector
<node
*> node_list
;
61 #define LIST_BUILTIN_CLASS_METHODS(x) \
73 #define BUILTIN_METHOD(class_name, method_name) \
74 node *builtin_##class_name##_##method_name(context *globals, context *ctx, tuple *args, dict *kwargs);
75 LIST_BUILTIN_CLASS_METHODS(BUILTIN_METHOD
)
78 inline node
*create_bool_const(bool b
);
84 virtual const char *node_type() { return "node"; }
86 virtual void mark_live() { error("mark_live unimplemented for %s", this->node_type()); }
87 #define MARK_LIVE_FN \
88 virtual void mark_live() { allocator->mark_live(this, sizeof(*this)); }
89 #define MARK_LIVE_SINGLETON_FN virtual void mark_live() { }
91 virtual bool is_bool() { return false; }
92 virtual bool is_dict() { return false; }
93 virtual bool is_file() { return false; }
94 virtual bool is_function() { return false; }
95 virtual bool is_int_const() { return false; }
96 virtual bool is_list() { return false; }
97 virtual bool is_tuple() { return false; }
98 virtual bool is_none() { return false; }
99 virtual bool is_set() { return false; }
100 virtual bool is_string() { return false; }
101 virtual bool bool_value() { error("bool_value unimplemented for %s", this->node_type()); return false; }
102 virtual int_t
int_value() { error("int_value unimplemented for %s", this->node_type()); return 0; }
103 virtual std::string
string_value() { error("string_value unimplemented for %s", this->node_type()); return NULL
; }
104 virtual node_list
*list_value() { error("list_value unimplemented for %s", this->node_type()); return NULL
; }
106 #define UNIMP_OP(NAME) \
107 virtual node *__##NAME##__(node *rhs) { error(#NAME " unimplemented for %s", this->node_type()); return NULL; }
123 #define UNIMP_CMP_OP(NAME) \
124 virtual bool _##NAME(node *rhs) { error(#NAME " unimplemented for %s", this->node_type()); return false; } \
125 node *__##NAME##__(node *rhs) { return create_bool_const(this->_##NAME(rhs)); }
136 #define UNIMP_UNOP(NAME) \
137 virtual node *__##NAME##__() { error(#NAME " unimplemented for %s", this->node_type()); return NULL; }
145 node
*__getattr__(node
*rhs
);
147 node
*__is__(node
*rhs
);
148 node
*__isnot__(node
*rhs
);
152 virtual node
*__ncontains__(node
*rhs
) { return this->__contains__(rhs
)->__not__(); }
154 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) { error("call unimplemented for %s", this->node_type()); return NULL
; }
155 virtual void __delitem__(node
*rhs
) { error("delitem unimplemented for %s", this->node_type()); }
156 virtual node
*__getitem__(node
*rhs
) { error("getitem unimplemented for %s", this->node_type()); return NULL
; }
157 virtual node
*__getitem__(int index
) { error("getitem unimplemented for %s", this->node_type()); return NULL
; }
158 virtual node
*__iter__() { error("iter unimplemented for %s", this->node_type()); }
159 virtual node
*next() { error("next unimplemented for %s", this->node_type()); }
160 virtual void __setattr__(node
*rhs
, node
*key
) { error("setattr unimplemented for %s", this->node_type()); }
161 virtual void __setitem__(node
*key
, node
*value
) { error("setitem unimplemented for %s", this->node_type()); }
162 virtual node
*__slice__(node
*start
, node
*end
, node
*step
) { error("slice unimplemented for %s", this->node_type()); return NULL
; }
164 // unwrapped versions
165 virtual int_t
len() { error("len unimplemented for %s", this->node_type()); return 0; }
166 virtual node
*getattr(const char *rhs
) { error("getattr unimplemented (%s) for %s", rhs
, this->node_type()); return NULL
; }
167 virtual int_t
hash() { error("hash unimplemented for %s", this->node_type()); return 0; }
168 virtual std::string
repr() { error("repr unimplemented for %s", this->node_type()); return NULL
; }
169 virtual std::string
str() { return repr(); }
179 context(uint32_t size
, node
**symbols
) {
180 this->parent_ctx
= NULL
;
181 this->symbols
= symbols
;
182 this->sym_len
= size
;
184 context(context
*parent_ctx
, uint32_t size
, node
**symbols
) {
185 this->parent_ctx
= parent_ctx
;
186 this->symbols
= symbols
;
187 this->sym_len
= size
;
190 void mark_live(bool free_ctx
) {
192 for (uint32_t i
= 0; i
< this->sym_len
; i
++)
193 if (this->symbols
[i
])
194 this->symbols
[i
]->mark_live();
195 if (this->parent_ctx
)
196 this->parent_ctx
->mark_live(false);
199 void store(uint32_t idx
, node
*obj
) {
200 this->symbols
[idx
] = obj
;
202 node
*load(uint32_t idx
) {
203 return this->symbols
[idx
];
207 class none_const
: public node
{
209 // For some reason this causes errors without an argument to the constructor...
210 none_const(int_t value
) { }
211 const char *node_type() { return "none"; }
213 MARK_LIVE_SINGLETON_FN
215 virtual bool is_none() { return true; }
216 virtual bool bool_value() { return false; }
218 virtual bool _eq(node
*rhs
);
219 virtual int_t
hash() { return 0; }
220 virtual std::string
repr() { return std::string("None"); }
223 class int_const
: public node
{
228 int_const(int_t value
) {
231 const char *node_type() { return "int"; }
235 virtual bool is_int_const() { return true; }
236 virtual int_t
int_value() { return this->value
; }
237 virtual bool bool_value() { return this->value
!= 0; }
239 #define INT_OP(NAME, OP) \
240 virtual int_t _##NAME(node *rhs) { \
241 return this->int_value() OP rhs->int_value(); \
243 virtual node *__##NAME##__(node *rhs) { \
244 return new(allocator) int_const(this->_##NAME(rhs)); \
257 #define CMP_OP(NAME, OP) \
258 virtual bool _##NAME(node *rhs) { \
259 return this->int_value() OP rhs->int_value(); \
269 #define INT_UNOP(NAME, OP) \
270 virtual node *__##NAME##__() { \
271 return new(allocator) int_const(OP this->int_value()); \
277 virtual int_t
hash() { return this->value
; }
278 virtual node
*getattr(const char *key
);
279 virtual std::string
repr();
282 class int_const_singleton
: public int_const
{
284 int_const_singleton(int_t value
) : int_const(value
) { }
286 MARK_LIVE_SINGLETON_FN
289 class bool_const
: public node
{
294 bool_const(bool value
) {
297 const char *node_type() { return "bool"; }
299 MARK_LIVE_SINGLETON_FN
301 virtual bool is_bool() { return true; }
302 virtual bool bool_value() { return this->value
; }
303 virtual int_t
int_value() { return (int_t
)this->value
; }
305 #define BOOL_AS_INT_OP(NAME, OP) \
306 virtual node *__##NAME##__(node *rhs) { \
307 if (rhs->is_int_const() || rhs->is_bool()) \
308 return new(allocator) int_const(this->int_value() OP rhs->int_value()); \
309 error(#NAME " error in bool"); \
312 BOOL_AS_INT_OP(add
, +)
313 BOOL_AS_INT_OP(floordiv
, /)
314 BOOL_AS_INT_OP(lshift
, <<)
315 BOOL_AS_INT_OP(mod
, %)
316 BOOL_AS_INT_OP(mul
, *)
317 BOOL_AS_INT_OP(rshift
, >>)
318 BOOL_AS_INT_OP(sub
, -)
320 #define BOOL_INT_CHECK_OP(NAME, OP) \
321 virtual node *__##NAME##__(node *rhs) { \
322 if (rhs->is_bool()) \
323 return new(allocator) bool_const((bool)(this->int_value() OP rhs->int_value())); \
324 else if (rhs->is_int_const()) \
325 return new(allocator) int_const(this->int_value() OP rhs->int_value()); \
326 error(#NAME " error in bool"); \
330 BOOL_INT_CHECK_OP(and, &)
331 BOOL_INT_CHECK_OP(or, |)
332 BOOL_INT_CHECK_OP(xor, ^)
334 #define BOOL_OP(NAME, OP) \
335 virtual bool _##NAME(node *rhs) { \
336 if (rhs->is_int_const() || rhs->is_bool()) \
337 return this->int_value() OP rhs->int_value(); \
338 error(#NAME " error in bool"); \
348 virtual int_t
hash() { return (int_t
)this->value
; }
349 virtual std::string
repr();
352 class string_const
: public node
{
354 class str_iter
: public node
{
356 string_const
*parent
;
357 std::string::iterator it
;
360 str_iter(string_const
*s
) {
362 it
= s
->value
.begin();
364 const char *node_type() { return "str_iter"; }
366 virtual void mark_live() {
367 if (!allocator
->mark_live(this, sizeof(*this)))
368 this->parent
->mark_live();
371 virtual node
*next() {
372 if (this->it
== this->parent
->value
.end())
378 return new(allocator
) string_const(ret
);
385 string_const(std::string value
) {
388 const char *node_type() { return "str"; }
392 virtual bool is_string() { return true; }
393 virtual std::string
string_value() { return this->value
; }
394 virtual bool bool_value() { return this->len() != 0; }
396 std::string::iterator
begin() { return value
.begin(); }
397 std::string::iterator
end() { return value
.end(); }
399 #define STRING_OP(NAME, OP) \
400 virtual bool _##NAME(node *rhs) { \
401 if (rhs->is_string()) \
402 return this->string_value() OP rhs->string_value(); \
403 error(#NAME " unimplemented"); \
414 virtual node
*__mod__(node
*rhs
);
415 virtual node
*__add__(node
*rhs
);
416 virtual node
*__mul__(node
*rhs
);
418 virtual node
*getattr(const char *key
);
420 virtual node
*__getitem__(node
*rhs
) {
421 if (!rhs
->is_int_const()) {
422 error("getitem unimplemented");
425 return new(allocator
) string_const(value
.substr(rhs
->int_value(), 1));
428 virtual int_t
hash() {
429 int_t hashkey
= 14695981039346656037ull;
430 for (std::string::iterator c
= this->begin(); c
!= this->end(); c
++) {
432 hashkey
*= 1099511628211ll;
436 virtual int_t
len() {
437 return value
.length();
439 virtual node
*__slice__(node
*start
, node
*end
, node
*step
) {
440 if ((!start
->is_none() && !start
->is_int_const()) ||
441 (!end
->is_none() && !end
->is_int_const()) ||
442 (!step
->is_none() && !step
->is_int_const()))
443 error("slice error");
444 int_t lo
= start
->is_none() ? 0 : start
->int_value();
445 int_t hi
= end
->is_none() ? value
.length() : end
->int_value();
446 int_t st
= step
->is_none() ? 1 : step
->int_value();
448 error("slice step != 1 not supported for string");
449 return new(allocator
) string_const(this->value
.substr(lo
, hi
- lo
+ 1));
451 virtual std::string
repr() {
452 bool has_single_quotes
= false;
453 bool has_double_quotes
= false;
454 for (std::string::iterator it
= this->begin(); it
!= this->end(); ++it
) {
457 has_single_quotes
= true;
459 has_double_quotes
= true;
461 bool use_double_quotes
= has_single_quotes
&& !has_double_quotes
;
462 std::string
s(use_double_quotes
? "\"" : "'");
463 for (std::string::iterator it
= this->begin(); it
!= this->end(); ++it
) {
473 else if ((c
== '\'') && !use_double_quotes
)
478 s
+= use_double_quotes
? "\"" : "'";
481 virtual std::string
str() { return this->value
; }
482 virtual node
*__iter__() { return new(allocator
) str_iter(this); }
485 class string_const_singleton
: public string_const
{
490 string_const_singleton(std::string value
, int_t hashkey
) : string_const(value
), hashkey(hashkey
) { }
492 MARK_LIVE_SINGLETON_FN
494 virtual int_t
hash() {
495 return this->hashkey
;
499 class list
: public node
{
501 class list_iter
: public node
{
504 node_list::iterator it
;
509 it
= l
->items
.begin();
511 const char *node_type() { return "list_iter"; }
513 virtual void mark_live() {
514 if (!allocator
->mark_live(this, sizeof(*this)))
515 this->parent
->mark_live();
518 virtual node
*next() {
519 if (this->it
== this->parent
->items
.end())
521 node
*ret
= *this->it
;
531 list(int_t n
, node
**items
): items(n
) {
532 for (int_t i
= 0; i
< n
; i
++)
533 this->items
[i
] = items
[i
];
535 const char *node_type() { return "list"; }
537 virtual void mark_live() {
538 if (!allocator
->mark_live(this, sizeof(*this))) {
539 for (size_t i
= 0; i
< this->items
.size(); i
++)
540 this->items
[i
]->mark_live();
544 void append(node
*obj
) {
545 items
.push_back(obj
);
547 void prepend(node
*obj
) {
548 items
.insert(items
.begin(), obj
);
551 // would be nice if STL wasn't stupid, and this was one line...
552 node
*popped
= items
.back();
556 node_list::iterator
begin() { return items
.begin(); }
557 node_list::iterator
end() { return items
.end(); }
558 int_t
index(int_t base
) {
560 base
= items
.size() + base
;
564 virtual bool is_list() { return true; }
565 virtual node_list
*list_value() { return &items
; }
566 virtual bool bool_value() { return this->len() != 0; }
568 virtual node
*__add__(node
*rhs
);
569 virtual node
*__mul__(node
*rhs
);
571 virtual node
*__contains__(node
*key
) {
573 for (size_t i
= 0; i
< this->items
.size(); i
++)
574 if (this->items
[i
]->_eq(key
)) {
578 return create_bool_const(found
);
580 virtual void __delitem__(node
*rhs
) {
581 if (!rhs
->is_int_const()) {
582 error("delitem unimplemented");
585 node_list::iterator f
= items
.begin() + this->index(rhs
->int_value());
588 virtual node
*__getitem__(int idx
) {
589 return this->items
[this->index(idx
)];
591 virtual node
*__getitem__(node
*rhs
) {
592 if (!rhs
->is_int_const()) {
593 error("getitem unimplemented");
596 return this->__getitem__(rhs
->int_value());
598 virtual int_t
len() {
599 return this->items
.size();
601 virtual void __setitem__(node
*key
, node
*value
) {
602 if (!key
->is_int_const())
603 error("error in list.setitem");
604 int_t idx
= key
->int_value();
605 items
[this->index(idx
)] = value
;
607 virtual node
*__slice__(node
*start
, node
*end
, node
*step
) {
608 if ((!start
->is_none() && !start
->is_int_const()) ||
609 (!end
->is_none() && !end
->is_int_const()) ||
610 (!step
->is_none() && !step
->is_int_const()))
611 error("slice error");
612 int_t lo
= start
->is_none() ? 0 : start
->int_value();
613 int_t hi
= end
->is_none() ? items
.size() : end
->int_value();
614 int_t st
= step
->is_none() ? 1 : step
->int_value();
615 list
*new_list
= new(allocator
) list();
616 for (; st
> 0 ? (lo
< hi
) : (lo
> hi
); lo
+= st
)
617 new_list
->append(items
[lo
]);
620 virtual std::string
repr() {
621 std::string new_string
= "[";
623 for (node_list::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++) {
627 new_string
+= (*i
)->repr();
632 virtual node
*getattr(const char *key
);
633 virtual node
*__iter__() { return new(allocator
) list_iter(this); }
636 class tuple
: public node
{
638 class tuple_iter
: public node
{
641 node_list::iterator it
;
644 tuple_iter(tuple
*t
) {
646 it
= t
->items
.begin();
648 const char *node_type() { return "tuple_iter"; }
650 virtual void mark_live() {
651 if (!allocator
->mark_live(this, sizeof(*this)))
652 this->parent
->mark_live();
655 virtual node
*next() {
656 if (this->it
== this->parent
->items
.end())
658 node
*ret
= *this->it
;
668 tuple(int_t n
, node
**items
): items(n
) {
669 for (int_t i
= 0; i
< n
; i
++)
670 this->items
[i
] = items
[i
];
672 const char *node_type() { return "tuple"; }
673 virtual bool is_tuple() { return true; }
675 virtual void mark_live() {
676 if (!allocator
->mark_live(this, sizeof(*this))) {
677 for (size_t i
= 0; i
< this->items
.size(); i
++)
678 this->items
[i
]->mark_live();
682 int_t
index(int_t base
) {
684 base
= items
.size() + base
;
688 virtual bool bool_value() { return this->len() != 0; }
690 virtual node
*__contains__(node
*key
) {
692 for (size_t i
= 0; i
< this->items
.size(); i
++)
693 if (this->items
[i
]->_eq(key
)) {
697 return create_bool_const(found
);
699 virtual node
*__getitem__(int idx
) {
700 return this->items
[this->index(idx
)];
702 virtual node
*__getitem__(node
*rhs
) {
703 if (!rhs
->is_int_const()) {
704 error("getitem unimplemented");
707 return this->__getitem__(rhs
->int_value());
709 virtual int_t
len() {
710 return this->items
.size();
712 virtual std::string
repr() {
713 std::string new_string
= "(";
715 for (node_list::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++) {
719 new_string
+= (*i
)->repr();
721 if (this->items
.size() == 1)
726 virtual node
*__iter__() { return new(allocator
) tuple_iter(this); }
729 class dict
: public node
{
731 class dict_iter
: public node
{
734 node_dict::iterator it
;
739 it
= d
->items
.begin();
741 const char *node_type() { return "dict_iter"; }
743 virtual void mark_live() {
744 if (!allocator
->mark_live(this, sizeof(*this)))
745 this->parent
->mark_live();
748 virtual node
*next() {
749 if (this->it
== this->parent
->items
.end())
751 node
*ret
= this->it
->second
.first
;
761 const char *node_type() { return "dict"; }
763 virtual void mark_live() {
764 if (!allocator
->mark_live(this, sizeof(*this))) {
765 for (node_dict::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++) {
766 i
->second
.first
->mark_live();
767 i
->second
.second
->mark_live();
772 node
*lookup(node
*key
) {
774 if (key
->is_int_const())
775 hashkey
= key
->int_value();
777 hashkey
= key
->hash();
778 node_dict::const_iterator v
= this->items
.find(hashkey
);
779 if (v
== this->items
.end())
781 node
*k
= v
->second
.first
;
784 return v
->second
.second
;
786 node_dict::iterator
begin() { return items
.begin(); }
787 node_dict::iterator
end() { return items
.end(); }
789 virtual bool is_dict() { return true; }
790 virtual bool bool_value() { return this->len() != 0; }
792 virtual node
*__contains__(node
*key
) {
793 return create_bool_const(this->lookup(key
) != NULL
);
795 virtual node
*__getitem__(node
*key
) {
796 node
*value
= this->lookup(key
);
798 error("cannot find %s in dict", key
->repr().c_str());
801 virtual int_t
len() {
802 return this->items
.size();
804 virtual void __setitem__(node
*key
, node
*value
) {
806 if (key
->is_int_const())
807 hashkey
= key
->int_value();
809 hashkey
= key
->hash();
810 items
[hashkey
] = node_pair(key
, value
);
812 virtual std::string
repr() {
813 std::string new_string
= "{";
815 for (node_dict::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++) {
819 new_string
+= i
->second
.first
->repr() + ": " + i
->second
.second
->repr();
824 virtual node
*getattr(const char *key
);
825 virtual node
*__iter__() { return new(allocator
) dict_iter(this); }
828 class set
: public node
{
830 class set_iter
: public node
{
833 node_set::iterator it
;
838 it
= s
->items
.begin();
840 const char *node_type() { return "set_iter"; }
842 virtual void mark_live() {
843 if (!allocator
->mark_live(this, sizeof(*this)))
844 this->parent
->mark_live();
847 virtual node
*next() {
848 if (this->it
== this->parent
->items
.end())
850 node
*ret
= this->it
->second
;
860 const char *node_type() { return "set"; }
862 virtual void mark_live() {
863 if (!allocator
->mark_live(this, sizeof(*this))) {
864 for (node_set::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++)
865 i
->second
->mark_live();
869 node
*lookup(node
*key
) {
871 if (key
->is_int_const())
872 hashkey
= key
->int_value();
874 hashkey
= key
->hash();
875 node_set::const_iterator v
= this->items
.find(hashkey
);
876 if (v
== this->items
.end() || !v
->second
->_eq(key
))
880 void add(node
*key
) {
882 if (key
->is_int_const())
883 hashkey
= key
->int_value();
885 hashkey
= key
->hash();
886 items
[hashkey
] = key
;
889 virtual bool is_set() { return true; }
890 virtual bool bool_value() { return this->len() != 0; }
892 virtual node
*__contains__(node
*key
) {
893 return create_bool_const(this->lookup(key
) != NULL
);
895 virtual int_t
len() {
896 return this->items
.size();
898 virtual std::string
repr() {
899 if (!this->items
.size())
901 std::string new_string
= "{";
903 for (node_set::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++) {
907 new_string
+= i
->second
->repr();
912 virtual node
*getattr(const char *key
);
913 virtual node
*__iter__() { return new(allocator
) set_iter(this); }
916 class object
: public node
{
922 this->items
= new(allocator
) dict();
924 const char *node_type() { return "object"; }
926 virtual void mark_live() {
927 if (!allocator
->mark_live(this, sizeof(*this)))
928 this->items
->mark_live();
931 virtual bool bool_value() { return true; }
933 virtual node
*getattr(const char *key
) {
934 return items
->__getitem__(new(allocator
) string_const(key
));
936 virtual void __setattr__(node
*key
, node
*value
) {
937 items
->__setitem__(key
, value
);
939 virtual bool _eq(node
*rhs
) {
944 class file
: public node
{
949 file(const char *path
, const char *mode
) {
950 f
= fopen(path
, mode
);
952 error("%s: file not found", path
);
954 const char *node_type() { return "file"; }
958 node
*read(int_t len
) {
959 static char buf
[64*1024];
960 size_t ret
= fread(buf
, 1, len
, this->f
);
961 std::string
s(buf
, ret
);
962 return new(allocator
) string_const(s
);
965 virtual bool is_file() { return true; }
968 class range
: public node
{
970 class range_iter
: public node
{
972 int_t start
, end
, step
;
975 range_iter(range
*r
) {
976 this->start
= r
->start
;
978 this->step
= r
->step
;
980 const char *node_type() { return "range_iter"; }
984 virtual node
*next() {
986 if (this->start
>= this->end
)
990 if (this->start
<= this->end
)
993 node
*ret
= new(allocator
) int_const(this->start
);
994 this->start
+= this->step
;
999 int_t start
, end
, step
;
1002 range(int_t start
, int_t end
, int_t step
) {
1003 this->start
= start
;
1007 const char *node_type() { return "range"; }
1011 virtual node
*__iter__() { return new(allocator
) range_iter(this); }
1013 virtual std::string
repr() {
1016 sprintf(buf
, "range(%ld, %ld)", this->start
, this->end
);
1019 sprintf(buf
, "range(%ld, %ld, %ld)", this->start
, this->end
, this->step
);
1025 typedef node
*(*fptr
)(context
*globals
, context
*parent_ctx
, tuple
*args
, dict
*kwargs
);
1027 class bound_method
: public node
{
1033 bound_method(node
*self
, node
*function
) {
1035 this->function
= function
;
1037 const char *node_type() { return "bound_method"; }
1039 virtual void mark_live() {
1040 if (!allocator
->mark_live(this, sizeof(*this))) {
1041 this->self
->mark_live();
1042 this->function
->mark_live();
1046 virtual bool is_function() { return true; } // XXX is it?
1048 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1049 int_t len
= args
->len();
1050 node
*new_args
[len
+ 1];
1051 new_args
[0] = this->self
;
1052 for (int_t i
= 0; i
< len
; i
++)
1053 new_args
[i
+1] = args
->__getitem__(i
);
1054 args
= new(allocator
) tuple(len
+ 1, new_args
);
1055 return this->function
->__call__(globals
, ctx
, args
, kwargs
);
1059 class function_def
: public node
{
1064 function_def(fptr base_function
) {
1065 this->base_function
= base_function
;
1067 const char *node_type() { return "function"; }
1071 virtual bool is_function() { return true; }
1073 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1074 return this->base_function(globals
, ctx
, args
, kwargs
);
1078 class class_def
: public node
{
1084 class_def(std::string name
, void (*creator
)(class_def
*)) {
1086 this->items
= new(allocator
) dict();
1089 const char *node_type() { return "class"; }
1091 virtual void mark_live() {
1092 if (!allocator
->mark_live(this, sizeof(*this)))
1093 this->items
->mark_live();
1096 node
*load(const char *name
) {
1097 return items
->__getitem__(new(allocator
) string_const(name
));
1099 void store(const char *name
, node
*value
) {
1100 items
->__setitem__(new(allocator
) string_const(name
), value
);
1103 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1104 node
*init
= this->load("__init__");
1105 node
*obj
= new(allocator
) object();
1107 obj
->__setattr__(new(allocator
) string_const("__class__"), this);
1109 // Create bound methods
1110 for (node_dict::iterator i
= items
->begin(); i
!= items
->end(); i
++)
1111 if (i
->second
.second
->is_function())
1112 obj
->__setattr__(i
->second
.first
, new(allocator
) bound_method(obj
, i
->second
.second
));
1114 ((list
*)args
)->prepend(obj
);
1115 init
->__call__(globals
, ctx
, args
, kwargs
);
1118 virtual node
*getattr(const char *attr
) {
1119 return this->load(attr
);
1121 virtual std::string
repr() {
1122 return std::string("<class '") + this->name
+ "'>";
1126 bool_const
bool_singleton_True(true);
1127 bool_const
bool_singleton_False(false);
1128 none_const
none_singleton(0);
1130 inline node
*create_bool_const(bool b
) {
1131 return b
? &bool_singleton_True
: &bool_singleton_False
;
1134 #define NO_KWARGS_N_ARGS(name, n_args) \
1135 if (kwargs->len()) \
1136 error(name "() does not take keyword arguments"); \
1137 if (args->len() != n_args) \
1138 error("wrong number of arguments to " name "()")
1140 #define NO_KWARGS_MAX_ARGS(name, max_args) \
1141 if (kwargs->len()) \
1142 error(name "() does not take keyword arguments"); \
1143 if (args->len() > max_args) \
1144 error("too many arguments to " name "()")
1147 class builtin_method_def
: public function_def
{
1149 builtin_method_def(fptr base_function
): function_def(base_function
) {}
1151 MARK_LIVE_SINGLETON_FN
1154 #define BUILTIN_METHOD(class_name, method_name) builtin_method_def builtin_method_##class_name##_##method_name(builtin_##class_name##_##method_name);
1155 LIST_BUILTIN_CLASS_METHODS(BUILTIN_METHOD
)
1156 #undef BUILTIN_METHOD
1158 void _dummy__create_(class_def
*ctx
) {}
1160 class builtin_class_def_singleton
: public class_def
{
1162 builtin_class_def_singleton(std::string name
): class_def(name
, _dummy__create_
) {}
1164 MARK_LIVE_SINGLETON_FN
1167 class bool_class_def_singleton
: public builtin_class_def_singleton
{
1169 bool_class_def_singleton(): builtin_class_def_singleton("bool") {}
1171 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1172 NO_KWARGS_MAX_ARGS("bool", 1);
1174 return &bool_singleton_False
;
1175 node
*arg
= args
->__getitem__(0);
1176 return create_bool_const(arg
->bool_value());
1180 class dict_class_def_singleton
: public builtin_class_def_singleton
{
1182 dict_class_def_singleton(): builtin_class_def_singleton("dict") {}
1184 virtual node
*getattr(const char *key
) {
1185 if (!strcmp(key
, "get"))
1186 return &builtin_method_dict_get
;
1187 if (!strcmp(key
, "keys"))
1188 return &builtin_method_dict_keys
;
1189 error("dict has no attribute %s", key
);
1193 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1194 NO_KWARGS_N_ARGS("dict", 0);
1195 return new(allocator
) dict();
1199 class enumerate_class_def_singleton
: public builtin_class_def_singleton
{
1201 class enumerate_obj
: public node
{
1207 enumerate_obj(node
*iter
) {
1211 const char *node_type() { return "enumerate_obj"; }
1213 virtual void mark_live() {
1214 if (!allocator
->mark_live(this, sizeof(*this)))
1215 this->iter
->mark_live();
1218 virtual node
*__iter__() { return this; }
1219 virtual node
*next() {
1220 node
*item
= this->iter
->next();
1224 pair
[0] = new(allocator
) int_const(this->i
++);
1226 return new(allocator
) tuple(2, pair
);
1229 virtual std::string
repr() { return "<enumerate object>"; }
1233 enumerate_class_def_singleton(): builtin_class_def_singleton("enumerate") {}
1235 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1236 NO_KWARGS_N_ARGS("enumerate", 1);
1237 node
*arg
= args
->__getitem__(0);
1238 node
*iter
= arg
->__iter__();
1239 return new(allocator
) enumerate_obj(iter
);
1243 class int_class_def_singleton
: public builtin_class_def_singleton
{
1245 int_class_def_singleton(): builtin_class_def_singleton("int") {}
1247 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1248 NO_KWARGS_MAX_ARGS("int", 2);
1250 return new(allocator
) int_const(0);
1251 node
*arg
= args
->__getitem__(0);
1252 if (arg
->is_int_const()) {
1253 if (args
->len() != 1)
1254 error("int() cannot accept a base when passed an int");
1257 if (arg
->is_string()) {
1259 if (args
->len() == 2) {
1260 node
*base_node
= args
->__getitem__(1);
1261 if (!base_node
->is_int_const())
1262 error("base must be an int");
1263 base
= base_node
->int_value();
1264 if ((base
< 0) || (base
== 1) || (base
> 36))
1265 error("base must be 0 or 2-36");
1267 error("base 0 unsupported at present");
1269 std::string str
= arg
->string_value();
1270 const char *s
= str
.c_str();
1286 if ((c
>= '0') && (c
<= '9'))
1288 else if ((c
>= 'a') && (c
<= 'z'))
1289 digit
= c
- 'a' + 10;
1290 else if ((c
>= 'A') && (c
<= 'Z'))
1291 digit
= c
- 'A' + 10;
1293 error("unexpected digit");
1295 error("digit not valid in base");
1296 value
= value
*base
+ digit
;
1298 return new(allocator
) int_const(sign
*value
);
1300 error("don't know how to handle argument to int()");
1304 class list_class_def_singleton
: public builtin_class_def_singleton
{
1306 list_class_def_singleton(): builtin_class_def_singleton("list") {}
1308 virtual node
*getattr(const char *key
) {
1309 if (!strcmp(key
, "append"))
1310 return &builtin_method_list_append
;
1311 if (!strcmp(key
, "index"))
1312 return &builtin_method_list_index
;
1313 if (!strcmp(key
, "pop"))
1314 return &builtin_method_list_pop
;
1315 error("list has no attribute %s", key
);
1318 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1319 NO_KWARGS_MAX_ARGS("list", 1);
1320 list
*ret
= new(allocator
) list();
1323 node
*arg
= args
->__getitem__(0);
1324 node
*iter
= arg
->__iter__();
1325 while (node
*item
= iter
->next())
1331 class range_class_def_singleton
: public builtin_class_def_singleton
{
1333 range_class_def_singleton(): builtin_class_def_singleton("range") {}
1335 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1336 int_t start
= 0, end
, step
= 1;
1338 if (args
->len() == 1)
1339 end
= args
->__getitem__(0)->int_value();
1340 else if (args
->len() == 2) {
1341 start
= args
->__getitem__(0)->int_value();
1342 end
= args
->__getitem__(1)->int_value();
1344 else if (args
->len() == 3) {
1345 start
= args
->__getitem__(0)->int_value();
1346 end
= args
->__getitem__(1)->int_value();
1347 step
= args
->__getitem__(2)->int_value();
1350 error("too many arguments to range()");
1352 return new(allocator
) range(start
, end
, step
);
1356 class reversed_class_def_singleton
: public builtin_class_def_singleton
{
1358 class reversed_obj
: public node
{
1365 reversed_obj(node
*parent
, int_t len
) {
1366 this->parent
= parent
;
1370 const char *node_type() { return "reversed_obj"; }
1372 virtual void mark_live() {
1373 if (!allocator
->mark_live(this, sizeof(*this)))
1374 this->parent
->mark_live();
1377 virtual node
*__iter__() { return this; }
1378 virtual node
*next() {
1381 int_t cur
= this->i
++;
1382 return this->parent
->__getitem__(this->len
- 1 - cur
);
1385 virtual std::string
repr() { return "<reversed object>"; }
1389 reversed_class_def_singleton(): builtin_class_def_singleton("reversed") {}
1391 // XXX This will actually work on dictionaries if they have keys of 0..len-1.
1392 // Logically speaking it doesn't make sense to have reversed() of a dictionary
1393 // do anything, but the Python docs imply that __len__ and __getitem__ are
1394 // sufficient. This seems like a documentation error.
1395 node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1396 NO_KWARGS_N_ARGS("reversed", 1);
1397 node
*item
= args
->__getitem__(0);
1398 int_t len
= item
->len();
1399 return new(allocator
) reversed_obj(item
, len
);
1403 class set_class_def_singleton
: public builtin_class_def_singleton
{
1405 set_class_def_singleton(): builtin_class_def_singleton("set") {}
1407 virtual node
*getattr(const char *key
) {
1408 if (!strcmp(key
, "add"))
1409 return &builtin_method_set_add
;
1410 error("set has no attribute %s", key
);
1414 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1415 NO_KWARGS_MAX_ARGS("set", 1);
1416 set
*ret
= new(allocator
) set();
1419 node
*arg
= args
->__getitem__(0);
1420 node
*iter
= arg
->__iter__();
1421 while (node
*item
= iter
->next())
1427 class str_class_def_singleton
: public builtin_class_def_singleton
{
1429 str_class_def_singleton(): builtin_class_def_singleton("str") {}
1431 virtual node
*getattr(const char *key
) {
1432 if (!strcmp(key
, "join"))
1433 return &builtin_method_str_join
;
1434 if (!strcmp(key
, "split"))
1435 return &builtin_method_str_split
;
1436 if (!strcmp(key
, "upper"))
1437 return &builtin_method_str_upper
;
1438 if (!strcmp(key
, "startswith"))
1439 return &builtin_method_str_startswith
;
1440 error("str has no attribute %s", key
);
1443 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1444 NO_KWARGS_MAX_ARGS("str", 1);
1446 return new(allocator
) string_const("");
1447 node
*arg
= args
->__getitem__(0);
1448 return arg
->__str__();
1452 class tuple_class_def_singleton
: public builtin_class_def_singleton
{
1454 tuple_class_def_singleton(): builtin_class_def_singleton("tuple") {}
1456 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1457 NO_KWARGS_MAX_ARGS("tuple", 1);
1459 return new(allocator
) tuple
;
1460 node
*arg
= args
->__getitem__(0);
1461 node
*iter
= arg
->__iter__();
1463 while (node
*item
= iter
->next())
1465 return new(allocator
) tuple(l
.size(), &l
[0]);
1469 class zip_class_def_singleton
: public builtin_class_def_singleton
{
1471 class zip_obj
: public node
{
1477 zip_obj(node
*iter1
, node
*iter2
) {
1478 this->iter1
= iter1
;
1479 this->iter2
= iter2
;
1481 const char *node_type() { return "zip_obj"; }
1483 virtual void mark_live() {
1484 if (!allocator
->mark_live(this, sizeof(*this))) {
1485 this->iter1
->mark_live();
1486 this->iter2
->mark_live();
1490 virtual node
*__iter__() { return this; }
1491 virtual node
*next() {
1492 node
*item1
= this->iter1
->next();
1493 node
*item2
= this->iter2
->next();
1494 if (!item1
|| !item2
)
1499 return new(allocator
) tuple(2, pair
);
1502 virtual std::string
repr() { return "<zip object>"; }
1506 zip_class_def_singleton(): builtin_class_def_singleton("zip") {}
1508 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1509 NO_KWARGS_N_ARGS("zip", 2);
1510 node
*iter1
= args
->__getitem__(0)->__iter__();
1511 node
*iter2
= args
->__getitem__(1)->__iter__();
1512 return new(allocator
) zip_obj(iter1
, iter2
);
1516 #define BUILTIN_CLASS(name) name##_class_def_singleton builtin_class_##name;
1517 LIST_BUILTIN_CLASSES(BUILTIN_CLASS
)
1518 #undef BUILTIN_CLASS
1520 node
*node::__getattr__(node
*key
) {
1521 if (!key
->is_string())
1522 error("getattr with non-string");
1523 return this->getattr(key
->string_value().c_str());
1526 node
*node::__hash__() {
1527 return new(allocator
) int_const(this->hash());
1530 node
*node::__len__() {
1531 return new(allocator
) int_const(this->len());
1534 node
*node::__not__() {
1535 return create_bool_const(!this->bool_value());
1538 node
*node::__is__(node
*rhs
) {
1539 return create_bool_const(this == rhs
);
1542 node
*node::__isnot__(node
*rhs
) {
1543 return create_bool_const(this != rhs
);
1546 node
*node::__repr__() {
1547 return new(allocator
) string_const(this->repr());
1550 node
*node::__str__() {
1551 return new(allocator
) string_const(this->str());
1554 bool none_const::_eq(node
*rhs
) {
1555 return (this == rhs
);
1558 node
*int_const::getattr(const char *key
) {
1559 if (!strcmp(key
, "__class__"))
1560 return &builtin_class_int
;
1561 error("int has no attribute %s", key
);
1565 std::string
int_const::repr() {
1567 sprintf(buf
, "%" PRId64
, this->value
);
1568 return std::string(buf
);
1571 std::string
bool_const::repr() {
1572 return std::string(this->value
? "True" : "False");
1575 node
*list::__add__(node
*rhs
) {
1576 if (!rhs
->is_list())
1577 error("list add error");
1578 list
*plist
= new(allocator
) list();
1579 node_list
*rhs_list
= rhs
->list_value();
1580 for (node_list::iterator i
= this->begin(); i
!= this->end(); i
++)
1582 for (node_list::iterator i
= rhs_list
->begin(); i
!= rhs_list
->end(); i
++)
1587 node
*list::__mul__(node
*rhs
) {
1588 if (!rhs
->is_int_const())
1589 error("list mul error");
1590 list
*plist
= new(allocator
) list();
1591 for (int_t x
= rhs
->int_value(); x
> 0; x
--)
1592 for (node_list::iterator i
= this->begin(); i
!= this->end(); i
++)
1597 node
*list::getattr(const char *key
) {
1598 if (!strcmp(key
, "__class__"))
1599 return &builtin_class_list
;
1600 return new(allocator
) bound_method(this, builtin_class_list
.getattr(key
));
1603 node
*dict::getattr(const char *key
) {
1604 if (!strcmp(key
, "__class__"))
1605 return &builtin_class_dict
;
1606 return new(allocator
) bound_method(this, builtin_class_dict
.getattr(key
));
1609 node
*set::getattr(const char *key
) {
1610 if (!strcmp(key
, "__class__"))
1611 return &builtin_class_set
;
1612 return new(allocator
) bound_method(this, builtin_class_set
.getattr(key
));
1615 node
*string_const::getattr(const char *key
) {
1616 if (!strcmp(key
, "__class__"))
1617 return &builtin_class_str
;
1618 return new(allocator
) bound_method(this, builtin_class_str
.getattr(key
));
1621 // This entire function is very stupidly implemented.
1622 node
*string_const::__mod__(node
*rhs
) {
1623 std::ostringstream new_string
;
1624 if (!rhs
->is_tuple()) {
1625 node
*tuple_item
[1] = {rhs
};
1626 tuple
*t
= new(allocator
) tuple(1, tuple_item
);
1630 for (const char *c
= value
.c_str(); *c
; c
++) {
1632 char fmt_buf
[64], buf
[64];
1633 char *fmt
= fmt_buf
;
1636 // Copy over formatting data: only numbers allowed as modifiers now
1637 while (*c
&& isdigit(*c
))
1640 if ((unsigned)(fmt
- fmt_buf
) >= sizeof(buf
))
1641 error("I do believe you've made a terrible mistake whilst formatting a string!");
1642 if (args
>= rhs
->len())
1643 error("not enough arguments for string format");
1644 node
*arg
= rhs
->__getitem__(args
++);
1648 sprintf(buf
, fmt_buf
, arg
->str().c_str());
1650 else if (*c
== 'd' || *c
== 'i' || *c
== 'X') {
1655 sprintf(buf
, fmt_buf
, arg
->int_value());
1657 else if (*c
== 'c') {
1661 if (arg
->is_string())
1662 char_value
= (unsigned char)arg
->string_value()[0];
1664 char_value
= arg
->int_value();
1665 sprintf(buf
, fmt_buf
, char_value
);
1668 error("bad format specifier '%c' in \"%s\"", *c
, value
.c_str());
1674 return new(allocator
) string_const(new_string
.str());
1677 node
*string_const::__add__(node
*rhs
) {
1678 if (!rhs
->is_string())
1679 error("bad argument to str.add");
1680 std::string new_string
= this->value
+ rhs
->string_value();
1681 return new(allocator
) string_const(new_string
);
1684 node
*string_const::__mul__(node
*rhs
) {
1685 if (!rhs
->is_int_const() || rhs
->int_value() < 0)
1686 error("bad argument to str.mul");
1687 std::string new_string
;
1688 for (int_t i
= 0; i
< rhs
->int_value(); i
++)
1689 new_string
+= this->value
;
1690 return new(allocator
) string_const(new_string
);
1693 ////////////////////////////////////////////////////////////////////////////////
1694 // Builtins ////////////////////////////////////////////////////////////////////
1695 ////////////////////////////////////////////////////////////////////////////////
1697 class builtin_function_def
: public function_def
{
1702 builtin_function_def(const char *name
, fptr base_function
): function_def(base_function
) {
1705 const char *node_type() { return "builtin_function"; }
1707 MARK_LIVE_SINGLETON_FN
1709 virtual std::string
repr() {
1710 return std::string("<built-in function ") + this->name
+ ">";
1714 node
*builtin_dict_get(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1715 NO_KWARGS_N_ARGS("dict.get", 3);
1716 node
*self
= args
->__getitem__(0);
1717 node
*key
= args
->__getitem__(1);
1719 node
*value
= ((dict
*)self
)->lookup(key
);
1721 value
= args
->__getitem__(2);
1726 node
*builtin_dict_keys(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1727 NO_KWARGS_N_ARGS("dict.keys", 1);
1728 dict
*self
= (dict
*)args
->__getitem__(0);
1730 list
*plist
= new(allocator
) list();
1731 for (node_dict::iterator i
= self
->begin(); i
!= self
->end(); i
++)
1732 plist
->append(i
->second
.first
);
1737 node
*builtin_fread(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1738 NO_KWARGS_N_ARGS("fread", 2);
1739 node
*f
= args
->__getitem__(0);
1740 node
*len
= args
->__getitem__(1);
1741 if (!f
->is_file() || !len
->is_int_const())
1742 error("bad arguments to fread()");
1743 return ((file
*)f
)->read(len
->int_value());
1746 node
*builtin_isinstance(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1747 NO_KWARGS_N_ARGS("isinstance", 2);
1748 node
*obj
= args
->__getitem__(0);
1749 node
*arg_class
= args
->__getitem__(1);
1751 node
*obj_class
= obj
->getattr("__class__");
1752 return create_bool_const(obj_class
== arg_class
);
1755 node
*builtin_len(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1756 NO_KWARGS_N_ARGS("len", 1);
1757 return args
->__getitem__(0)->__len__();
1760 node
*builtin_list_append(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1761 NO_KWARGS_N_ARGS("list.append", 2);
1762 node
*self
= args
->__getitem__(0);
1763 node
*item
= args
->__getitem__(1);
1765 ((list
*)self
)->append(item
);
1767 return &none_singleton
;
1770 node
*builtin_list_index(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1771 NO_KWARGS_N_ARGS("list.index", 2);
1772 node
*self
= args
->__getitem__(0);
1773 node
*key
= args
->__getitem__(1);
1775 for (int_t i
= 0; i
< self
->len(); i
++)
1776 if (self
->__getitem__(i
)->_eq(key
))
1777 return new(allocator
) int_const(i
);
1778 error("item not found in list");
1779 return &none_singleton
;
1782 node
*builtin_list_pop(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1783 NO_KWARGS_N_ARGS("pop", 1);
1784 list
*self
= (list
*)args
->__getitem__(0);
1789 node
*builtin_open(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1790 NO_KWARGS_N_ARGS("open", 2);
1791 node
*path
= args
->__getitem__(0);
1792 node
*mode
= args
->__getitem__(1);
1793 if (!path
->is_string() || !mode
->is_string())
1794 error("bad arguments to open()");
1795 file
*f
= new(allocator
) file(path
->string_value().c_str(), mode
->string_value().c_str());
1799 node
*builtin_ord(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1800 NO_KWARGS_N_ARGS("ord", 1);
1801 node
*arg
= args
->__getitem__(0);
1802 if (!arg
->is_string() || arg
->len() != 1)
1803 error("bad arguments to ord()");
1804 return new(allocator
) int_const((unsigned char)arg
->string_value()[0]);
1807 node
*builtin_print(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1808 std::string new_string
;
1809 for (int_t i
= 0; i
< args
->len(); i
++) {
1812 node
*s
= args
->__getitem__(i
);
1813 new_string
+= s
->str();
1815 printf("%s\n", new_string
.c_str());
1816 return &none_singleton
;
1819 node
*builtin_print_nonl(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1820 NO_KWARGS_N_ARGS("print_nonl", 1);
1821 node
*s
= args
->__getitem__(0);
1822 printf("%s", s
->str().c_str());
1823 return &none_singleton
;
1826 node
*builtin_repr(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1827 NO_KWARGS_N_ARGS("repr", 1);
1828 node
*arg
= args
->__getitem__(0);
1829 return arg
->__repr__();
1832 node
*builtin_set_add(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1833 NO_KWARGS_N_ARGS("set.add", 2);
1834 node
*self
= args
->__getitem__(0);
1835 node
*item
= args
->__getitem__(1);
1837 ((set
*)self
)->add(item
);
1839 return &none_singleton
;
1842 bool compare_nodes(node
*lhs
, node
*rhs
) {
1843 return lhs
->_lt(rhs
);
1846 node
*builtin_sorted(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1847 NO_KWARGS_N_ARGS("sorted", 1);
1848 node
*arg
= args
->__getitem__(0);
1849 node
*iter
= arg
->__iter__();
1851 while (node
*item
= iter
->next())
1852 new_list
.push_back(item
);
1853 std::stable_sort(new_list
.begin(), new_list
.end(), compare_nodes
);
1854 return new(allocator
) list(new_list
.size(), &new_list
[0]);
1857 node
*builtin_str_join(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1858 NO_KWARGS_N_ARGS("str.join", 2);
1859 node
*self
= args
->__getitem__(0);
1860 node
*joined
= args
->__getitem__(1);
1861 if (!self
->is_string())
1862 error("bad arguments to str.join()");
1863 node
*iter
= joined
->__iter__();
1866 while (node
*item
= iter
->next()) {
1870 s
+= self
->string_value();
1873 return new(allocator
) string_const(s
);
1876 node
*builtin_str_split(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1877 NO_KWARGS_N_ARGS("str.split", 2);
1878 node
*self
= args
->__getitem__(0);
1879 node
*item
= args
->__getitem__(1);
1880 if (!self
->is_string() || !item
->is_string() || (item
->len() != 1))
1881 error("bad argument to str.upper()");
1882 string_const
*str
= (string_const
*)self
;
1883 char split
= item
->string_value()[0];
1884 list
*ret
= new(allocator
) list
;
1886 for (std::string::iterator c
= str
->begin(); c
!= str
->end(); ++c
) {
1888 ret
->append(new(allocator
) string_const(s
));
1895 ret
->append(new(allocator
) string_const(s
));
1899 node
*builtin_str_upper(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1900 NO_KWARGS_N_ARGS("str.upper", 1);
1901 node
*self
= args
->__getitem__(0);
1902 if (!self
->is_string())
1903 error("bad argument to str.upper()");
1904 string_const
*str
= (string_const
*)self
;
1906 std::string new_string
;
1907 for (std::string::iterator c
= str
->begin(); c
!= str
->end(); c
++)
1908 new_string
+= toupper(*c
);
1910 return new(allocator
) string_const(new_string
);
1913 node
*builtin_str_startswith(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1914 NO_KWARGS_N_ARGS("str.startswith", 2);
1915 node
*self
= args
->__getitem__(0);
1916 node
*prefix
= args
->__getitem__(1);
1917 if (!self
->is_string() || !prefix
->is_string())
1918 error("bad arguments to str.startswith()");
1920 std::string s1
= self
->string_value();
1921 std::string s2
= prefix
->string_value();
1922 return create_bool_const(s1
.compare(0, s2
.size(), s2
) == 0);
1925 #define BUILTIN_FUNCTION(name) builtin_function_def builtin_function_##name(#name, builtin_##name);
1926 LIST_BUILTIN_FUNCTIONS(BUILTIN_FUNCTION
)
1927 #undef BUILTIN_FUNCTION
1929 void init_context(context
*ctx
, int_t argc
, char **argv
) {
1930 #define BUILTIN_FUNCTION(name) ctx->store(sym_id_##name, &builtin_function_##name);
1931 LIST_BUILTIN_FUNCTIONS(BUILTIN_FUNCTION
)
1932 #undef BUILTIN_FUNCTION
1934 #define BUILTIN_CLASS(name) ctx->store(sym_id_##name, &builtin_class_##name);
1935 LIST_BUILTIN_CLASSES(BUILTIN_CLASS
)
1936 #undef BUILTIN_CLASS
1938 ctx
->store(sym_id___name__
, new(allocator
) string_const("__main__"));
1939 list
*plist
= new(allocator
) list();
1940 for (int_t a
= 0; a
< argc
; a
++)
1941 plist
->append(new(allocator
) string_const(argv
[a
]));
1942 ctx
->store(sym_id___args__
, plist
);
1945 void collect_garbage(context
*ctx
, node
*ret_val
) {
1946 static int gc_tick
= 0;
1947 if (++gc_tick
> 128) {
1950 allocator
->mark_dead();
1952 ctx
->mark_live(ret_val
!= NULL
);
1955 ret_val
->mark_live();