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) \
75 #define BUILTIN_METHOD(class_name, method_name) \
76 node *builtin_##class_name##_##method_name(context *globals, context *ctx, tuple *args, dict *kwargs);
77 LIST_BUILTIN_CLASS_METHODS(BUILTIN_METHOD
)
80 inline node
*create_bool_const(bool b
);
86 virtual const char *node_type() { return "node"; }
88 virtual void mark_live() { error("mark_live unimplemented for %s", this->node_type()); }
89 #define MARK_LIVE_FN \
90 virtual void mark_live() { allocator->mark_live(this, sizeof(*this)); }
91 #define MARK_LIVE_SINGLETON_FN virtual void mark_live() { }
93 virtual bool is_bool() { return false; }
94 virtual bool is_dict() { return false; }
95 virtual bool is_file() { return false; }
96 virtual bool is_function() { return false; }
97 virtual bool is_int_const() { return false; }
98 virtual bool is_list() { return false; }
99 virtual bool is_tuple() { return false; }
100 virtual bool is_none() { return false; }
101 virtual bool is_set() { return false; }
102 virtual bool is_string() { return false; }
103 virtual bool bool_value() { error("bool_value unimplemented for %s", this->node_type()); return false; }
104 virtual int_t
int_value() { error("int_value unimplemented for %s", this->node_type()); return 0; }
105 virtual std::string
string_value() { error("string_value unimplemented for %s", this->node_type()); return NULL
; }
106 virtual node_list
*list_value() { error("list_value unimplemented for %s", this->node_type()); return NULL
; }
108 #define UNIMP_OP(NAME) \
109 virtual node *__##NAME##__(node *rhs) { error(#NAME " unimplemented for %s", this->node_type()); return NULL; }
125 #define UNIMP_CMP_OP(NAME) \
126 virtual bool _##NAME(node *rhs) { error(#NAME " unimplemented for %s", this->node_type()); return false; } \
127 node *__##NAME##__(node *rhs) { return create_bool_const(this->_##NAME(rhs)); }
138 #define UNIMP_UNOP(NAME) \
139 virtual node *__##NAME##__() { error(#NAME " unimplemented for %s", this->node_type()); return NULL; }
147 node
*__getattr__(node
*rhs
);
149 node
*__is__(node
*rhs
);
150 node
*__isnot__(node
*rhs
);
154 virtual node
*__ncontains__(node
*rhs
) { return this->__contains__(rhs
)->__not__(); }
156 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) { error("call unimplemented for %s", this->node_type()); return NULL
; }
157 virtual void __delitem__(node
*rhs
) { error("delitem unimplemented for %s", this->node_type()); }
158 virtual node
*__getitem__(node
*rhs
) { error("getitem unimplemented for %s", this->node_type()); return NULL
; }
159 virtual node
*__getitem__(int index
) { error("getitem unimplemented for %s", this->node_type()); return NULL
; }
160 virtual node
*__iter__() { error("iter unimplemented for %s", this->node_type()); }
161 virtual node
*next() { error("next unimplemented for %s", this->node_type()); }
162 virtual void __setattr__(node
*rhs
, node
*key
) { error("setattr unimplemented for %s", this->node_type()); }
163 virtual void __setitem__(node
*key
, node
*value
) { error("setitem unimplemented for %s", this->node_type()); }
164 virtual node
*__slice__(node
*start
, node
*end
, node
*step
) { error("slice unimplemented for %s", this->node_type()); return NULL
; }
166 // unwrapped versions
167 virtual int_t
len() { error("len unimplemented for %s", this->node_type()); return 0; }
168 virtual node
*getattr(const char *rhs
) { error("getattr unimplemented (%s) for %s", rhs
, this->node_type()); return NULL
; }
169 virtual int_t
hash() { error("hash unimplemented for %s", this->node_type()); return 0; }
170 virtual std::string
repr() { error("repr unimplemented for %s", this->node_type()); return NULL
; }
171 virtual std::string
str() { return repr(); }
181 context(uint32_t size
, node
**symbols
) {
182 this->parent_ctx
= NULL
;
183 this->symbols
= symbols
;
184 this->sym_len
= size
;
186 context(context
*parent_ctx
, uint32_t size
, node
**symbols
) {
187 this->parent_ctx
= parent_ctx
;
188 this->symbols
= symbols
;
189 this->sym_len
= size
;
192 void mark_live(bool free_ctx
) {
194 for (uint32_t i
= 0; i
< this->sym_len
; i
++)
195 if (this->symbols
[i
])
196 this->symbols
[i
]->mark_live();
197 if (this->parent_ctx
)
198 this->parent_ctx
->mark_live(false);
201 void store(uint32_t idx
, node
*obj
) {
202 this->symbols
[idx
] = obj
;
204 node
*load(uint32_t idx
) {
205 node
*ret
= this->symbols
[idx
];
207 error("name is not defined");
212 class none_const
: public node
{
214 // For some reason this causes errors without an argument to the constructor...
215 none_const(int_t value
) { }
216 const char *node_type() { return "none"; }
218 MARK_LIVE_SINGLETON_FN
220 virtual bool is_none() { return true; }
221 virtual bool bool_value() { return false; }
223 virtual bool _eq(node
*rhs
);
224 virtual int_t
hash() { return 0; }
225 virtual std::string
repr() { return std::string("None"); }
228 class int_const
: public node
{
233 int_const(int_t value
) {
236 const char *node_type() { return "int"; }
240 virtual bool is_int_const() { return true; }
241 virtual int_t
int_value() { return this->value
; }
242 virtual bool bool_value() { return this->value
!= 0; }
244 #define INT_OP(NAME, OP) \
245 virtual int_t _##NAME(node *rhs) { \
246 return this->int_value() OP rhs->int_value(); \
248 virtual node *__##NAME##__(node *rhs) { \
249 return new(allocator) int_const(this->_##NAME(rhs)); \
262 #define CMP_OP(NAME, OP) \
263 virtual bool _##NAME(node *rhs) { \
264 return this->int_value() OP rhs->int_value(); \
274 #define INT_UNOP(NAME, OP) \
275 virtual node *__##NAME##__() { \
276 return new(allocator) int_const(OP this->int_value()); \
282 virtual int_t
hash() { return this->value
; }
283 virtual node
*getattr(const char *key
);
284 virtual std::string
repr();
287 class int_const_singleton
: public int_const
{
289 int_const_singleton(int_t value
) : int_const(value
) { }
291 MARK_LIVE_SINGLETON_FN
294 class bool_const
: public node
{
299 bool_const(bool value
) {
302 const char *node_type() { return "bool"; }
304 MARK_LIVE_SINGLETON_FN
306 virtual bool is_bool() { return true; }
307 virtual bool bool_value() { return this->value
; }
308 virtual int_t
int_value() { return (int_t
)this->value
; }
310 #define BOOL_AS_INT_OP(NAME, OP) \
311 virtual node *__##NAME##__(node *rhs) { \
312 if (rhs->is_int_const() || rhs->is_bool()) \
313 return new(allocator) int_const(this->int_value() OP rhs->int_value()); \
314 error(#NAME " error in bool"); \
317 BOOL_AS_INT_OP(add
, +)
318 BOOL_AS_INT_OP(floordiv
, /)
319 BOOL_AS_INT_OP(lshift
, <<)
320 BOOL_AS_INT_OP(mod
, %)
321 BOOL_AS_INT_OP(mul
, *)
322 BOOL_AS_INT_OP(rshift
, >>)
323 BOOL_AS_INT_OP(sub
, -)
325 #define BOOL_INT_CHECK_OP(NAME, OP) \
326 virtual node *__##NAME##__(node *rhs) { \
327 if (rhs->is_bool()) \
328 return new(allocator) bool_const((bool)(this->int_value() OP rhs->int_value())); \
329 else if (rhs->is_int_const()) \
330 return new(allocator) int_const(this->int_value() OP rhs->int_value()); \
331 error(#NAME " error in bool"); \
335 BOOL_INT_CHECK_OP(and, &)
336 BOOL_INT_CHECK_OP(or, |)
337 BOOL_INT_CHECK_OP(xor, ^)
339 #define BOOL_OP(NAME, OP) \
340 virtual bool _##NAME(node *rhs) { \
341 if (rhs->is_int_const() || rhs->is_bool()) \
342 return this->int_value() OP rhs->int_value(); \
343 error(#NAME " error in bool"); \
353 virtual int_t
hash() { return (int_t
)this->value
; }
354 virtual std::string
repr();
357 class string_const
: public node
{
359 class str_iter
: public node
{
361 string_const
*parent
;
362 std::string::iterator it
;
365 str_iter(string_const
*s
) {
367 it
= s
->value
.begin();
369 const char *node_type() { return "str_iter"; }
371 virtual void mark_live() {
372 if (!allocator
->mark_live(this, sizeof(*this)))
373 this->parent
->mark_live();
376 virtual node
*next() {
377 if (this->it
== this->parent
->value
.end())
383 return new(allocator
) string_const(ret
);
390 string_const(std::string value
) {
393 const char *node_type() { return "str"; }
397 virtual bool is_string() { return true; }
398 virtual std::string
string_value() { return this->value
; }
399 virtual bool bool_value() { return this->len() != 0; }
401 const char *c_str() { return value
.c_str(); }
402 std::string::iterator
begin() { return value
.begin(); }
403 std::string::iterator
end() { return value
.end(); }
405 #define STRING_OP(NAME, OP) \
406 virtual bool _##NAME(node *rhs) { \
407 if (rhs->is_string()) \
408 return this->string_value() OP rhs->string_value(); \
409 error(#NAME " unimplemented"); \
420 virtual node
*__mod__(node
*rhs
);
421 virtual node
*__add__(node
*rhs
);
422 virtual node
*__mul__(node
*rhs
);
424 virtual node
*getattr(const char *key
);
426 virtual node
*__getitem__(node
*rhs
) {
427 if (!rhs
->is_int_const()) {
428 error("getitem unimplemented");
431 return new(allocator
) string_const(value
.substr(rhs
->int_value(), 1));
434 virtual int_t
hash() {
435 int_t hashkey
= 14695981039346656037ull;
436 for (std::string::iterator c
= this->begin(); c
!= this->end(); c
++) {
438 hashkey
*= 1099511628211ll;
442 virtual int_t
len() {
443 return value
.length();
445 virtual node
*__slice__(node
*start
, node
*end
, node
*step
) {
446 if ((!start
->is_none() && !start
->is_int_const()) ||
447 (!end
->is_none() && !end
->is_int_const()) ||
448 (!step
->is_none() && !step
->is_int_const()))
449 error("slice error");
450 int_t lo
= start
->is_none() ? 0 : start
->int_value();
451 int_t hi
= end
->is_none() ? value
.length() : end
->int_value();
452 int_t st
= step
->is_none() ? 1 : step
->int_value();
454 error("slice step != 1 not supported for string");
455 return new(allocator
) string_const(this->value
.substr(lo
, hi
- lo
+ 1));
457 virtual std::string
repr() {
458 bool has_single_quotes
= false;
459 bool has_double_quotes
= false;
460 for (std::string::iterator it
= this->begin(); it
!= this->end(); ++it
) {
463 has_single_quotes
= true;
465 has_double_quotes
= true;
467 bool use_double_quotes
= has_single_quotes
&& !has_double_quotes
;
468 std::string
s(use_double_quotes
? "\"" : "'");
469 for (std::string::iterator it
= this->begin(); it
!= this->end(); ++it
) {
479 else if ((c
== '\'') && !use_double_quotes
)
484 s
+= use_double_quotes
? "\"" : "'";
487 virtual std::string
str() { return this->value
; }
488 virtual node
*__iter__() { return new(allocator
) str_iter(this); }
491 class string_const_singleton
: public string_const
{
496 string_const_singleton(std::string value
, int_t hashkey
) : string_const(value
), hashkey(hashkey
) { }
498 MARK_LIVE_SINGLETON_FN
500 virtual int_t
hash() {
501 return this->hashkey
;
505 class list
: public node
{
507 class list_iter
: public node
{
510 node_list::iterator it
;
515 it
= l
->items
.begin();
517 const char *node_type() { return "list_iter"; }
519 virtual void mark_live() {
520 if (!allocator
->mark_live(this, sizeof(*this)))
521 this->parent
->mark_live();
524 virtual node
*next() {
525 if (this->it
== this->parent
->items
.end())
527 node
*ret
= *this->it
;
537 list(int_t n
, node
**items
): items(n
) {
538 for (int_t i
= 0; i
< n
; i
++)
539 this->items
[i
] = items
[i
];
541 const char *node_type() { return "list"; }
543 virtual void mark_live() {
544 if (!allocator
->mark_live(this, sizeof(*this))) {
545 for (size_t i
= 0; i
< this->items
.size(); i
++)
546 this->items
[i
]->mark_live();
550 void append(node
*obj
) {
551 items
.push_back(obj
);
553 void prepend(node
*obj
) {
554 items
.insert(items
.begin(), obj
);
557 // would be nice if STL wasn't stupid, and this was one line...
558 node
*popped
= items
.back();
562 node_list::iterator
begin() { return items
.begin(); }
563 node_list::iterator
end() { return items
.end(); }
564 int_t
index(int_t base
) {
565 int_t size
= items
.size();
566 if ((base
>= size
) || (base
< -size
))
567 error("list index out of range");
573 virtual bool is_list() { return true; }
574 virtual node_list
*list_value() { return &items
; }
575 virtual bool bool_value() { return this->len() != 0; }
577 virtual node
*__add__(node
*rhs
);
578 virtual node
*__mul__(node
*rhs
);
580 virtual node
*__contains__(node
*key
) {
582 for (size_t i
= 0; i
< this->items
.size(); i
++)
583 if (this->items
[i
]->_eq(key
)) {
587 return create_bool_const(found
);
589 virtual void __delitem__(node
*rhs
) {
590 if (!rhs
->is_int_const()) {
591 error("delitem unimplemented");
594 node_list::iterator f
= items
.begin() + this->index(rhs
->int_value());
597 virtual node
*__getitem__(int idx
) {
598 return this->items
[this->index(idx
)];
600 virtual node
*__getitem__(node
*rhs
) {
601 if (!rhs
->is_int_const()) {
602 error("getitem unimplemented");
605 return this->__getitem__(rhs
->int_value());
607 virtual int_t
len() {
608 return this->items
.size();
610 virtual void __setitem__(node
*key
, node
*value
) {
611 if (!key
->is_int_const())
612 error("error in list.setitem");
613 int_t idx
= key
->int_value();
614 items
[this->index(idx
)] = value
;
616 virtual node
*__slice__(node
*start
, node
*end
, node
*step
) {
617 if ((!start
->is_none() && !start
->is_int_const()) ||
618 (!end
->is_none() && !end
->is_int_const()) ||
619 (!step
->is_none() && !step
->is_int_const()))
620 error("slice error");
621 int_t lo
= start
->is_none() ? 0 : start
->int_value();
622 int_t hi
= end
->is_none() ? items
.size() : end
->int_value();
623 int_t st
= step
->is_none() ? 1 : step
->int_value();
624 list
*new_list
= new(allocator
) list();
625 for (; st
> 0 ? (lo
< hi
) : (lo
> hi
); lo
+= st
)
626 new_list
->append(items
[lo
]);
629 virtual std::string
repr() {
630 std::string new_string
= "[";
632 for (node_list::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++) {
636 new_string
+= (*i
)->repr();
641 virtual node
*getattr(const char *key
);
642 virtual node
*__iter__() { return new(allocator
) list_iter(this); }
645 class tuple
: public node
{
647 class tuple_iter
: public node
{
650 node_list::iterator it
;
653 tuple_iter(tuple
*t
) {
655 it
= t
->items
.begin();
657 const char *node_type() { return "tuple_iter"; }
659 virtual void mark_live() {
660 if (!allocator
->mark_live(this, sizeof(*this)))
661 this->parent
->mark_live();
664 virtual node
*next() {
665 if (this->it
== this->parent
->items
.end())
667 node
*ret
= *this->it
;
677 tuple(int_t n
, node
**items
): items(n
) {
678 for (int_t i
= 0; i
< n
; i
++)
679 this->items
[i
] = items
[i
];
681 const char *node_type() { return "tuple"; }
682 virtual bool is_tuple() { return true; }
684 virtual void mark_live() {
685 if (!allocator
->mark_live(this, sizeof(*this))) {
686 for (size_t i
= 0; i
< this->items
.size(); i
++)
687 this->items
[i
]->mark_live();
691 int_t
index(int_t base
) {
692 int_t size
= items
.size();
693 if ((base
>= size
) || (base
< -size
))
694 error("tuple index out of range");
700 virtual bool bool_value() { return this->len() != 0; }
702 virtual node
*__contains__(node
*key
) {
704 for (size_t i
= 0; i
< this->items
.size(); i
++)
705 if (this->items
[i
]->_eq(key
)) {
709 return create_bool_const(found
);
711 virtual node
*__getitem__(int idx
) {
712 return this->items
[this->index(idx
)];
714 virtual node
*__getitem__(node
*rhs
) {
715 if (!rhs
->is_int_const()) {
716 error("getitem unimplemented");
719 return this->__getitem__(rhs
->int_value());
721 virtual int_t
len() {
722 return this->items
.size();
724 virtual std::string
repr() {
725 std::string new_string
= "(";
727 for (node_list::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++) {
731 new_string
+= (*i
)->repr();
733 if (this->items
.size() == 1)
738 virtual node
*__iter__() { return new(allocator
) tuple_iter(this); }
741 class dict
: public node
{
743 class dict_iter
: public node
{
746 node_dict::iterator it
;
751 it
= d
->items
.begin();
753 const char *node_type() { return "dict_iter"; }
755 virtual void mark_live() {
756 if (!allocator
->mark_live(this, sizeof(*this)))
757 this->parent
->mark_live();
760 virtual node
*next() {
761 if (this->it
== this->parent
->items
.end())
763 node
*ret
= this->it
->second
.first
;
773 const char *node_type() { return "dict"; }
775 virtual void mark_live() {
776 if (!allocator
->mark_live(this, sizeof(*this))) {
777 for (node_dict::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++) {
778 i
->second
.first
->mark_live();
779 i
->second
.second
->mark_live();
784 node
*lookup(node
*key
) {
786 if (key
->is_int_const())
787 hashkey
= key
->int_value();
789 hashkey
= key
->hash();
790 node_dict::const_iterator v
= this->items
.find(hashkey
);
791 if (v
== this->items
.end())
793 node
*k
= v
->second
.first
;
796 return v
->second
.second
;
798 node_dict::iterator
begin() { return items
.begin(); }
799 node_dict::iterator
end() { return items
.end(); }
801 virtual bool is_dict() { return true; }
802 virtual bool bool_value() { return this->len() != 0; }
804 virtual node
*__contains__(node
*key
) {
805 return create_bool_const(this->lookup(key
) != NULL
);
807 virtual node
*__getitem__(node
*key
) {
808 node
*value
= this->lookup(key
);
810 error("cannot find %s in dict", key
->repr().c_str());
813 virtual int_t
len() {
814 return this->items
.size();
816 virtual void __setitem__(node
*key
, node
*value
) {
818 if (key
->is_int_const())
819 hashkey
= key
->int_value();
821 hashkey
= key
->hash();
822 items
[hashkey
] = node_pair(key
, value
);
824 virtual std::string
repr() {
825 std::string new_string
= "{";
827 for (node_dict::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++) {
831 new_string
+= i
->second
.first
->repr() + ": " + i
->second
.second
->repr();
836 virtual node
*getattr(const char *key
);
837 virtual node
*__iter__() { return new(allocator
) dict_iter(this); }
840 class set
: public node
{
842 class set_iter
: public node
{
845 node_set::iterator it
;
850 it
= s
->items
.begin();
852 const char *node_type() { return "set_iter"; }
854 virtual void mark_live() {
855 if (!allocator
->mark_live(this, sizeof(*this)))
856 this->parent
->mark_live();
859 virtual node
*next() {
860 if (this->it
== this->parent
->items
.end())
862 node
*ret
= this->it
->second
;
872 const char *node_type() { return "set"; }
874 virtual void mark_live() {
875 if (!allocator
->mark_live(this, sizeof(*this))) {
876 for (node_set::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++)
877 i
->second
->mark_live();
881 node
*lookup(node
*key
) {
883 if (key
->is_int_const())
884 hashkey
= key
->int_value();
886 hashkey
= key
->hash();
887 node_set::const_iterator v
= this->items
.find(hashkey
);
888 if (v
== this->items
.end() || !v
->second
->_eq(key
))
892 void add(node
*key
) {
894 if (key
->is_int_const())
895 hashkey
= key
->int_value();
897 hashkey
= key
->hash();
898 items
[hashkey
] = key
;
901 virtual bool is_set() { return true; }
902 virtual bool bool_value() { return this->len() != 0; }
904 virtual node
*__contains__(node
*key
) {
905 return create_bool_const(this->lookup(key
) != NULL
);
907 virtual int_t
len() {
908 return this->items
.size();
910 virtual std::string
repr() {
911 if (!this->items
.size())
913 std::string new_string
= "{";
915 for (node_set::iterator i
= this->items
.begin(); i
!= this->items
.end(); i
++) {
919 new_string
+= i
->second
->repr();
924 virtual node
*getattr(const char *key
);
925 virtual node
*__iter__() { return new(allocator
) set_iter(this); }
928 class object
: public node
{
934 this->items
= new(allocator
) dict();
936 const char *node_type() { return "object"; }
938 virtual void mark_live() {
939 if (!allocator
->mark_live(this, sizeof(*this)))
940 this->items
->mark_live();
943 virtual bool bool_value() { return true; }
945 virtual node
*getattr(const char *key
) {
946 return items
->__getitem__(new(allocator
) string_const(key
));
948 virtual void __setattr__(node
*key
, node
*value
) {
949 items
->__setitem__(key
, value
);
951 virtual bool _eq(node
*rhs
) {
956 class file
: public node
{
961 file(const char *path
, const char *mode
) {
962 f
= fopen(path
, mode
);
964 error("%s: file not found", path
);
966 const char *node_type() { return "file"; }
970 node
*read(int_t len
) {
971 static char buf
[64*1024];
972 size_t ret
= fread(buf
, 1, len
, this->f
);
973 std::string
s(buf
, ret
);
974 return new(allocator
) string_const(s
);
976 void write(string_const
*data
) {
977 size_t len
= data
->len();
978 const char *buf
= data
->c_str();
979 (void)fwrite(buf
, 1, len
, this->f
);
982 virtual bool is_file() { return true; }
984 virtual node
*getattr(const char *key
);
987 class range
: public node
{
989 class range_iter
: public node
{
991 int_t start
, end
, step
;
994 range_iter(range
*r
) {
995 this->start
= r
->start
;
997 this->step
= r
->step
;
999 const char *node_type() { return "range_iter"; }
1003 virtual node
*next() {
1005 if (this->start
>= this->end
)
1009 if (this->start
<= this->end
)
1012 node
*ret
= new(allocator
) int_const(this->start
);
1013 this->start
+= this->step
;
1018 int_t start
, end
, step
;
1021 range(int_t start
, int_t end
, int_t step
) {
1022 this->start
= start
;
1026 const char *node_type() { return "range"; }
1030 virtual node
*__iter__() { return new(allocator
) range_iter(this); }
1032 virtual std::string
repr() {
1035 sprintf(buf
, "range(%ld, %ld)", this->start
, this->end
);
1038 sprintf(buf
, "range(%ld, %ld, %ld)", this->start
, this->end
, this->step
);
1044 typedef node
*(*fptr
)(context
*globals
, context
*parent_ctx
, tuple
*args
, dict
*kwargs
);
1046 class bound_method
: public node
{
1052 bound_method(node
*self
, node
*function
) {
1054 this->function
= function
;
1056 const char *node_type() { return "bound_method"; }
1058 virtual void mark_live() {
1059 if (!allocator
->mark_live(this, sizeof(*this))) {
1060 this->self
->mark_live();
1061 this->function
->mark_live();
1065 virtual bool is_function() { return true; } // XXX is it?
1067 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1068 int_t len
= args
->len();
1069 node
*new_args
[len
+ 1];
1070 new_args
[0] = this->self
;
1071 for (int_t i
= 0; i
< len
; i
++)
1072 new_args
[i
+1] = args
->__getitem__(i
);
1073 args
= new(allocator
) tuple(len
+ 1, new_args
);
1074 return this->function
->__call__(globals
, ctx
, args
, kwargs
);
1078 class function_def
: public node
{
1083 function_def(fptr base_function
) {
1084 this->base_function
= base_function
;
1086 const char *node_type() { return "function"; }
1090 virtual bool is_function() { return true; }
1092 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1093 return this->base_function(globals
, ctx
, args
, kwargs
);
1097 class class_def
: public node
{
1103 class_def(std::string name
, void (*creator
)(class_def
*)) {
1105 this->items
= new(allocator
) dict();
1108 const char *node_type() { return "class"; }
1110 virtual void mark_live() {
1111 if (!allocator
->mark_live(this, sizeof(*this)))
1112 this->items
->mark_live();
1115 node
*load(const char *name
) {
1116 return items
->__getitem__(new(allocator
) string_const(name
));
1118 void store(const char *name
, node
*value
) {
1119 items
->__setitem__(new(allocator
) string_const(name
), value
);
1122 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1123 node
*init
= this->load("__init__");
1124 node
*obj
= new(allocator
) object();
1126 obj
->__setattr__(new(allocator
) string_const("__class__"), this);
1128 // Create bound methods
1129 for (node_dict::iterator i
= items
->begin(); i
!= items
->end(); i
++)
1130 if (i
->second
.second
->is_function())
1131 obj
->__setattr__(i
->second
.first
, new(allocator
) bound_method(obj
, i
->second
.second
));
1133 ((list
*)args
)->prepend(obj
);
1134 init
->__call__(globals
, ctx
, args
, kwargs
);
1137 virtual node
*getattr(const char *attr
) {
1138 return this->load(attr
);
1140 virtual std::string
repr() {
1141 return std::string("<class '") + this->name
+ "'>";
1145 bool_const
bool_singleton_True(true);
1146 bool_const
bool_singleton_False(false);
1147 none_const
none_singleton(0);
1149 inline node
*create_bool_const(bool b
) {
1150 return b
? &bool_singleton_True
: &bool_singleton_False
;
1153 #define NO_KWARGS_N_ARGS(name, n_args) \
1154 if (kwargs->len()) \
1155 error(name "() does not take keyword arguments"); \
1156 if (args->len() != n_args) \
1157 error("wrong number of arguments to " name "()")
1159 #define NO_KWARGS_MIN_MAX_ARGS(name, min_args, max_args) \
1160 if (kwargs->len()) \
1161 error(name "() does not take keyword arguments"); \
1162 if (args->len() < min_args) \
1163 error("too few arguments to " name "()"); \
1164 if (args->len() > max_args) \
1165 error("too many arguments to " name "()")
1168 class builtin_method_def
: public function_def
{
1170 builtin_method_def(fptr base_function
): function_def(base_function
) {}
1172 MARK_LIVE_SINGLETON_FN
1175 #define BUILTIN_METHOD(class_name, method_name) builtin_method_def builtin_method_##class_name##_##method_name(builtin_##class_name##_##method_name);
1176 LIST_BUILTIN_CLASS_METHODS(BUILTIN_METHOD
)
1177 #undef BUILTIN_METHOD
1179 void _dummy__create_(class_def
*ctx
) {}
1181 class builtin_class_def_singleton
: public class_def
{
1183 builtin_class_def_singleton(std::string name
): class_def(name
, _dummy__create_
) {}
1185 MARK_LIVE_SINGLETON_FN
1188 class bool_class_def_singleton
: public builtin_class_def_singleton
{
1190 bool_class_def_singleton(): builtin_class_def_singleton("bool") {}
1192 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1193 NO_KWARGS_MIN_MAX_ARGS("bool", 0, 1);
1195 return &bool_singleton_False
;
1196 node
*arg
= args
->__getitem__(0);
1197 return create_bool_const(arg
->bool_value());
1201 class dict_class_def_singleton
: public builtin_class_def_singleton
{
1203 dict_class_def_singleton(): builtin_class_def_singleton("dict") {}
1205 virtual node
*getattr(const char *key
) {
1206 if (!strcmp(key
, "get"))
1207 return &builtin_method_dict_get
;
1208 if (!strcmp(key
, "keys"))
1209 return &builtin_method_dict_keys
;
1210 error("dict has no attribute %s", key
);
1214 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1215 NO_KWARGS_N_ARGS("dict", 0);
1216 return new(allocator
) dict();
1220 class enumerate_class_def_singleton
: public builtin_class_def_singleton
{
1222 class enumerate_obj
: public node
{
1228 enumerate_obj(node
*iter
) {
1232 const char *node_type() { return "enumerate_obj"; }
1234 virtual void mark_live() {
1235 if (!allocator
->mark_live(this, sizeof(*this)))
1236 this->iter
->mark_live();
1239 virtual node
*__iter__() { return this; }
1240 virtual node
*next() {
1241 node
*item
= this->iter
->next();
1245 pair
[0] = new(allocator
) int_const(this->i
++);
1247 return new(allocator
) tuple(2, pair
);
1250 virtual std::string
repr() { return "<enumerate object>"; }
1254 enumerate_class_def_singleton(): builtin_class_def_singleton("enumerate") {}
1256 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1257 NO_KWARGS_N_ARGS("enumerate", 1);
1258 node
*arg
= args
->__getitem__(0);
1259 node
*iter
= arg
->__iter__();
1260 return new(allocator
) enumerate_obj(iter
);
1264 class int_class_def_singleton
: public builtin_class_def_singleton
{
1266 int_class_def_singleton(): builtin_class_def_singleton("int") {}
1268 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1269 NO_KWARGS_MIN_MAX_ARGS("int", 0, 2);
1271 return new(allocator
) int_const(0);
1272 node
*arg
= args
->__getitem__(0);
1273 if (arg
->is_int_const()) {
1274 if (args
->len() != 1)
1275 error("int() cannot accept a base when passed an int");
1278 if (arg
->is_bool()) {
1279 if (args
->len() != 1)
1280 error("int() cannot accept a base when passed a bool");
1281 return new(allocator
) int_const(arg
->int_value());
1283 if (arg
->is_string()) {
1285 if (args
->len() == 2) {
1286 node
*base_node
= args
->__getitem__(1);
1287 if (!base_node
->is_int_const())
1288 error("base must be an int");
1289 base
= base_node
->int_value();
1290 if ((base
< 0) || (base
== 1) || (base
> 36))
1291 error("base must be 0 or 2-36");
1293 error("base 0 unsupported at present");
1295 std::string str
= arg
->string_value();
1296 const char *s
= str
.c_str();
1312 if ((c
>= '0') && (c
<= '9'))
1314 else if ((c
>= 'a') && (c
<= 'z'))
1315 digit
= c
- 'a' + 10;
1316 else if ((c
>= 'A') && (c
<= 'Z'))
1317 digit
= c
- 'A' + 10;
1319 error("unexpected digit");
1321 error("digit not valid in base");
1322 value
= value
*base
+ digit
;
1324 return new(allocator
) int_const(sign
*value
);
1326 error("don't know how to handle argument to int()");
1330 class list_class_def_singleton
: public builtin_class_def_singleton
{
1332 list_class_def_singleton(): builtin_class_def_singleton("list") {}
1334 virtual node
*getattr(const char *key
) {
1335 if (!strcmp(key
, "append"))
1336 return &builtin_method_list_append
;
1337 if (!strcmp(key
, "index"))
1338 return &builtin_method_list_index
;
1339 if (!strcmp(key
, "pop"))
1340 return &builtin_method_list_pop
;
1341 error("list has no attribute %s", key
);
1344 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1345 NO_KWARGS_MIN_MAX_ARGS("list", 0, 1);
1346 list
*ret
= new(allocator
) list();
1349 node
*arg
= args
->__getitem__(0);
1350 node
*iter
= arg
->__iter__();
1351 while (node
*item
= iter
->next())
1357 class range_class_def_singleton
: public builtin_class_def_singleton
{
1359 range_class_def_singleton(): builtin_class_def_singleton("range") {}
1361 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1362 int_t start
= 0, end
, step
= 1;
1364 if (args
->len() == 1)
1365 end
= args
->__getitem__(0)->int_value();
1366 else if (args
->len() == 2) {
1367 start
= args
->__getitem__(0)->int_value();
1368 end
= args
->__getitem__(1)->int_value();
1370 else if (args
->len() == 3) {
1371 start
= args
->__getitem__(0)->int_value();
1372 end
= args
->__getitem__(1)->int_value();
1373 step
= args
->__getitem__(2)->int_value();
1376 error("too many arguments to range()");
1378 return new(allocator
) range(start
, end
, step
);
1382 class reversed_class_def_singleton
: public builtin_class_def_singleton
{
1384 class reversed_obj
: public node
{
1391 reversed_obj(node
*parent
, int_t len
) {
1392 this->parent
= parent
;
1396 const char *node_type() { return "reversed_obj"; }
1398 virtual void mark_live() {
1399 if (!allocator
->mark_live(this, sizeof(*this)))
1400 this->parent
->mark_live();
1403 virtual node
*__iter__() { return this; }
1404 virtual node
*next() {
1407 int_t cur
= this->i
++;
1408 return this->parent
->__getitem__(this->len
- 1 - cur
);
1411 virtual std::string
repr() { return "<reversed object>"; }
1415 reversed_class_def_singleton(): builtin_class_def_singleton("reversed") {}
1417 // XXX This will actually work on dictionaries if they have keys of 0..len-1.
1418 // Logically speaking it doesn't make sense to have reversed() of a dictionary
1419 // do anything, but the Python docs imply that __len__ and __getitem__ are
1420 // sufficient. This seems like a documentation error.
1421 node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1422 NO_KWARGS_N_ARGS("reversed", 1);
1423 node
*item
= args
->__getitem__(0);
1424 int_t len
= item
->len();
1425 return new(allocator
) reversed_obj(item
, len
);
1429 class set_class_def_singleton
: public builtin_class_def_singleton
{
1431 set_class_def_singleton(): builtin_class_def_singleton("set") {}
1433 virtual node
*getattr(const char *key
) {
1434 if (!strcmp(key
, "add"))
1435 return &builtin_method_set_add
;
1436 error("set has no attribute %s", key
);
1440 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1441 NO_KWARGS_MIN_MAX_ARGS("set", 0, 1);
1442 set
*ret
= new(allocator
) set();
1445 node
*arg
= args
->__getitem__(0);
1446 node
*iter
= arg
->__iter__();
1447 while (node
*item
= iter
->next())
1453 class str_class_def_singleton
: public builtin_class_def_singleton
{
1455 str_class_def_singleton(): builtin_class_def_singleton("str") {}
1457 virtual node
*getattr(const char *key
) {
1458 if (!strcmp(key
, "join"))
1459 return &builtin_method_str_join
;
1460 if (!strcmp(key
, "split"))
1461 return &builtin_method_str_split
;
1462 if (!strcmp(key
, "upper"))
1463 return &builtin_method_str_upper
;
1464 if (!strcmp(key
, "startswith"))
1465 return &builtin_method_str_startswith
;
1466 error("str has no attribute %s", key
);
1469 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1470 NO_KWARGS_MIN_MAX_ARGS("str", 0, 1);
1472 return new(allocator
) string_const("");
1473 node
*arg
= args
->__getitem__(0);
1474 return arg
->__str__();
1478 class tuple_class_def_singleton
: public builtin_class_def_singleton
{
1480 tuple_class_def_singleton(): builtin_class_def_singleton("tuple") {}
1482 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1483 NO_KWARGS_MIN_MAX_ARGS("tuple", 0, 1);
1485 return new(allocator
) tuple
;
1486 node
*arg
= args
->__getitem__(0);
1487 node
*iter
= arg
->__iter__();
1489 while (node
*item
= iter
->next())
1491 return new(allocator
) tuple(l
.size(), &l
[0]);
1495 class zip_class_def_singleton
: public builtin_class_def_singleton
{
1497 class zip_obj
: public node
{
1503 zip_obj(node
*iter1
, node
*iter2
) {
1504 this->iter1
= iter1
;
1505 this->iter2
= iter2
;
1507 const char *node_type() { return "zip_obj"; }
1509 virtual void mark_live() {
1510 if (!allocator
->mark_live(this, sizeof(*this))) {
1511 this->iter1
->mark_live();
1512 this->iter2
->mark_live();
1516 virtual node
*__iter__() { return this; }
1517 virtual node
*next() {
1518 node
*item1
= this->iter1
->next();
1519 node
*item2
= this->iter2
->next();
1520 if (!item1
|| !item2
)
1525 return new(allocator
) tuple(2, pair
);
1528 virtual std::string
repr() { return "<zip object>"; }
1532 zip_class_def_singleton(): builtin_class_def_singleton("zip") {}
1534 virtual node
*__call__(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1535 NO_KWARGS_N_ARGS("zip", 2);
1536 node
*iter1
= args
->__getitem__(0)->__iter__();
1537 node
*iter2
= args
->__getitem__(1)->__iter__();
1538 return new(allocator
) zip_obj(iter1
, iter2
);
1542 #define BUILTIN_CLASS(name) name##_class_def_singleton builtin_class_##name;
1543 LIST_BUILTIN_CLASSES(BUILTIN_CLASS
)
1544 #undef BUILTIN_CLASS
1546 node
*node::__getattr__(node
*key
) {
1547 if (!key
->is_string())
1548 error("getattr with non-string");
1549 return this->getattr(key
->string_value().c_str());
1552 node
*node::__hash__() {
1553 return new(allocator
) int_const(this->hash());
1556 node
*node::__len__() {
1557 return new(allocator
) int_const(this->len());
1560 node
*node::__not__() {
1561 return create_bool_const(!this->bool_value());
1564 node
*node::__is__(node
*rhs
) {
1565 return create_bool_const(this == rhs
);
1568 node
*node::__isnot__(node
*rhs
) {
1569 return create_bool_const(this != rhs
);
1572 node
*node::__repr__() {
1573 return new(allocator
) string_const(this->repr());
1576 node
*node::__str__() {
1577 return new(allocator
) string_const(this->str());
1580 bool none_const::_eq(node
*rhs
) {
1581 return (this == rhs
);
1584 node
*int_const::getattr(const char *key
) {
1585 if (!strcmp(key
, "__class__"))
1586 return &builtin_class_int
;
1587 error("int has no attribute %s", key
);
1591 std::string
int_const::repr() {
1593 sprintf(buf
, "%" PRId64
, this->value
);
1594 return std::string(buf
);
1597 std::string
bool_const::repr() {
1598 return std::string(this->value
? "True" : "False");
1601 node
*list::__add__(node
*rhs
) {
1602 if (!rhs
->is_list())
1603 error("list add error");
1604 list
*plist
= new(allocator
) list();
1605 node_list
*rhs_list
= rhs
->list_value();
1606 for (node_list::iterator i
= this->begin(); i
!= this->end(); i
++)
1608 for (node_list::iterator i
= rhs_list
->begin(); i
!= rhs_list
->end(); i
++)
1613 node
*list::__mul__(node
*rhs
) {
1614 if (!rhs
->is_int_const())
1615 error("list mul error");
1616 list
*plist
= new(allocator
) list();
1617 for (int_t x
= rhs
->int_value(); x
> 0; x
--)
1618 for (node_list::iterator i
= this->begin(); i
!= this->end(); i
++)
1623 node
*list::getattr(const char *key
) {
1624 if (!strcmp(key
, "__class__"))
1625 return &builtin_class_list
;
1626 return new(allocator
) bound_method(this, builtin_class_list
.getattr(key
));
1629 node
*dict::getattr(const char *key
) {
1630 if (!strcmp(key
, "__class__"))
1631 return &builtin_class_dict
;
1632 return new(allocator
) bound_method(this, builtin_class_dict
.getattr(key
));
1635 node
*set::getattr(const char *key
) {
1636 if (!strcmp(key
, "__class__"))
1637 return &builtin_class_set
;
1638 return new(allocator
) bound_method(this, builtin_class_set
.getattr(key
));
1641 node
*string_const::getattr(const char *key
) {
1642 if (!strcmp(key
, "__class__"))
1643 return &builtin_class_str
;
1644 return new(allocator
) bound_method(this, builtin_class_str
.getattr(key
));
1647 // This entire function is very stupidly implemented.
1648 node
*string_const::__mod__(node
*rhs
) {
1649 std::ostringstream new_string
;
1650 if (!rhs
->is_tuple()) {
1651 node
*tuple_item
[1] = {rhs
};
1652 tuple
*t
= new(allocator
) tuple(1, tuple_item
);
1656 for (const char *c
= value
.c_str(); *c
; c
++) {
1658 char fmt_buf
[64], buf
[64];
1659 char *fmt
= fmt_buf
;
1662 // Copy over formatting data: only numbers allowed as modifiers now
1663 while (*c
&& isdigit(*c
))
1666 if ((unsigned)(fmt
- fmt_buf
) >= sizeof(buf
))
1667 error("I do believe you've made a terrible mistake whilst formatting a string!");
1668 if (args
>= rhs
->len())
1669 error("not enough arguments for string format");
1670 node
*arg
= rhs
->__getitem__(args
++);
1674 sprintf(buf
, fmt_buf
, arg
->str().c_str());
1676 else if (*c
== 'd' || *c
== 'i' || *c
== 'X') {
1681 sprintf(buf
, fmt_buf
, arg
->int_value());
1683 else if (*c
== 'c') {
1687 if (arg
->is_string())
1688 char_value
= (unsigned char)arg
->string_value()[0];
1690 char_value
= arg
->int_value();
1691 sprintf(buf
, fmt_buf
, char_value
);
1694 error("bad format specifier '%c' in \"%s\"", *c
, value
.c_str());
1700 return new(allocator
) string_const(new_string
.str());
1703 node
*string_const::__add__(node
*rhs
) {
1704 if (!rhs
->is_string())
1705 error("bad argument to str.add");
1706 std::string new_string
= this->value
+ rhs
->string_value();
1707 return new(allocator
) string_const(new_string
);
1710 node
*string_const::__mul__(node
*rhs
) {
1711 if (!rhs
->is_int_const() || rhs
->int_value() < 0)
1712 error("bad argument to str.mul");
1713 std::string new_string
;
1714 for (int_t i
= 0; i
< rhs
->int_value(); i
++)
1715 new_string
+= this->value
;
1716 return new(allocator
) string_const(new_string
);
1719 node
*file::getattr(const char *key
) {
1720 if (!strcmp(key
, "read"))
1721 return new(allocator
) bound_method(this, &builtin_method_file_read
);
1722 if (!strcmp(key
, "write"))
1723 return new(allocator
) bound_method(this, &builtin_method_file_write
);
1724 error("file has no attribute %s", key
);
1728 ////////////////////////////////////////////////////////////////////////////////
1729 // Builtins ////////////////////////////////////////////////////////////////////
1730 ////////////////////////////////////////////////////////////////////////////////
1732 class builtin_function_def
: public function_def
{
1737 builtin_function_def(const char *name
, fptr base_function
): function_def(base_function
) {
1740 const char *node_type() { return "builtin_function"; }
1742 MARK_LIVE_SINGLETON_FN
1744 virtual std::string
repr() {
1745 return std::string("<built-in function ") + this->name
+ ">";
1749 node
*builtin_all(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1750 NO_KWARGS_N_ARGS("all", 1);
1751 node
*arg
= args
->__getitem__(0);
1752 node
*iter
= arg
->__iter__();
1753 while (node
*item
= iter
->next()) {
1754 if (!item
->bool_value())
1755 return &bool_singleton_False
;
1757 return &bool_singleton_True
;
1760 node
*builtin_any(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1761 NO_KWARGS_N_ARGS("any", 1);
1762 node
*arg
= args
->__getitem__(0);
1763 node
*iter
= arg
->__iter__();
1764 while (node
*item
= iter
->next()) {
1765 if (item
->bool_value())
1766 return &bool_singleton_True
;
1768 return &bool_singleton_False
;
1771 node
*builtin_dict_get(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1772 NO_KWARGS_N_ARGS("dict.get", 3);
1773 node
*self
= args
->__getitem__(0);
1774 node
*key
= args
->__getitem__(1);
1776 node
*value
= ((dict
*)self
)->lookup(key
);
1778 value
= args
->__getitem__(2);
1783 node
*builtin_dict_keys(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1784 NO_KWARGS_N_ARGS("dict.keys", 1);
1785 dict
*self
= (dict
*)args
->__getitem__(0);
1787 list
*plist
= new(allocator
) list();
1788 for (node_dict::iterator i
= self
->begin(); i
!= self
->end(); i
++)
1789 plist
->append(i
->second
.first
);
1794 node
*builtin_file_read(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1795 NO_KWARGS_N_ARGS("file.read", 2);
1796 node
*f
= args
->__getitem__(0);
1797 node
*len
= args
->__getitem__(1);
1798 if (!f
->is_file() || !len
->is_int_const())
1799 error("bad arguments to file.read()");
1800 return ((file
*)f
)->read(len
->int_value());
1803 node
*builtin_file_write(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1804 NO_KWARGS_N_ARGS("file.write", 2);
1805 node
*f
= args
->__getitem__(0);
1806 node
*data
= args
->__getitem__(1);
1807 if (!f
->is_file() || !data
->is_string())
1808 error("bad arguments to file.write()");
1809 ((file
*)f
)->write((string_const
*)data
);
1810 return &none_singleton
;
1813 node
*builtin_isinstance(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1814 NO_KWARGS_N_ARGS("isinstance", 2);
1815 node
*obj
= args
->__getitem__(0);
1816 node
*arg_class
= args
->__getitem__(1);
1818 node
*obj_class
= obj
->getattr("__class__");
1819 return create_bool_const(obj_class
== arg_class
);
1822 node
*builtin_len(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1823 NO_KWARGS_N_ARGS("len", 1);
1824 return args
->__getitem__(0)->__len__();
1827 node
*builtin_list_append(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1828 NO_KWARGS_N_ARGS("list.append", 2);
1829 node
*self
= args
->__getitem__(0);
1830 node
*item
= args
->__getitem__(1);
1832 ((list
*)self
)->append(item
);
1834 return &none_singleton
;
1837 node
*builtin_list_index(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1838 NO_KWARGS_N_ARGS("list.index", 2);
1839 node
*self
= args
->__getitem__(0);
1840 node
*key
= args
->__getitem__(1);
1842 for (int_t i
= 0; i
< self
->len(); i
++)
1843 if (self
->__getitem__(i
)->_eq(key
))
1844 return new(allocator
) int_const(i
);
1845 error("item not found in list");
1846 return &none_singleton
;
1849 node
*builtin_list_pop(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1850 NO_KWARGS_N_ARGS("pop", 1);
1851 list
*self
= (list
*)args
->__getitem__(0);
1856 node
*builtin_open(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1857 NO_KWARGS_N_ARGS("open", 2);
1858 node
*path
= args
->__getitem__(0);
1859 node
*mode
= args
->__getitem__(1);
1860 if (!path
->is_string() || !mode
->is_string())
1861 error("bad arguments to open()");
1862 file
*f
= new(allocator
) file(path
->string_value().c_str(), mode
->string_value().c_str());
1866 node
*builtin_ord(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1867 NO_KWARGS_N_ARGS("ord", 1);
1868 node
*arg
= args
->__getitem__(0);
1869 if (!arg
->is_string() || arg
->len() != 1)
1870 error("bad arguments to ord()");
1871 return new(allocator
) int_const((unsigned char)arg
->string_value()[0]);
1874 node
*builtin_print(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1875 std::string new_string
;
1876 for (int_t i
= 0; i
< args
->len(); i
++) {
1879 node
*s
= args
->__getitem__(i
);
1880 new_string
+= s
->str();
1882 printf("%s\n", new_string
.c_str());
1883 return &none_singleton
;
1886 node
*builtin_print_nonl(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1887 NO_KWARGS_N_ARGS("print_nonl", 1);
1888 node
*s
= args
->__getitem__(0);
1889 printf("%s", s
->str().c_str());
1890 return &none_singleton
;
1893 node
*builtin_repr(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1894 NO_KWARGS_N_ARGS("repr", 1);
1895 node
*arg
= args
->__getitem__(0);
1896 return arg
->__repr__();
1899 node
*builtin_set_add(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1900 NO_KWARGS_N_ARGS("set.add", 2);
1901 node
*self
= args
->__getitem__(0);
1902 node
*item
= args
->__getitem__(1);
1904 ((set
*)self
)->add(item
);
1906 return &none_singleton
;
1909 bool compare_nodes(node
*lhs
, node
*rhs
) {
1910 return lhs
->_lt(rhs
);
1913 node
*builtin_sorted(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1914 NO_KWARGS_N_ARGS("sorted", 1);
1915 node
*arg
= args
->__getitem__(0);
1916 node
*iter
= arg
->__iter__();
1918 while (node
*item
= iter
->next())
1919 new_list
.push_back(item
);
1920 std::stable_sort(new_list
.begin(), new_list
.end(), compare_nodes
);
1921 return new(allocator
) list(new_list
.size(), &new_list
[0]);
1924 node
*builtin_str_join(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1925 NO_KWARGS_N_ARGS("str.join", 2);
1926 node
*self
= args
->__getitem__(0);
1927 node
*joined
= args
->__getitem__(1);
1928 if (!self
->is_string())
1929 error("bad arguments to str.join()");
1930 node
*iter
= joined
->__iter__();
1933 while (node
*item
= iter
->next()) {
1937 s
+= self
->string_value();
1940 return new(allocator
) string_const(s
);
1943 node
*builtin_str_split(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1944 NO_KWARGS_MIN_MAX_ARGS("str.split", 1, 2);
1945 node
*self
= args
->__getitem__(0);
1946 node
*item
= (args
->len() == 2) ? args
->__getitem__(1) : &none_singleton
;
1947 // XXX Implement correct behavior for missing separator (not the same as ' ')
1948 if (item
== &none_singleton
)
1949 item
= new(allocator
) string_const(" ");
1950 if (!self
->is_string() || !item
->is_string() || (item
->len() != 1))
1951 error("bad argument to str.split()");
1952 string_const
*str
= (string_const
*)self
;
1953 char split
= item
->string_value()[0];
1954 list
*ret
= new(allocator
) list
;
1956 for (std::string::iterator c
= str
->begin(); c
!= str
->end(); ++c
) {
1958 ret
->append(new(allocator
) string_const(s
));
1965 ret
->append(new(allocator
) string_const(s
));
1969 node
*builtin_str_upper(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1970 NO_KWARGS_N_ARGS("str.upper", 1);
1971 node
*self
= args
->__getitem__(0);
1972 if (!self
->is_string())
1973 error("bad argument to str.upper()");
1974 string_const
*str
= (string_const
*)self
;
1976 std::string new_string
;
1977 for (std::string::iterator c
= str
->begin(); c
!= str
->end(); c
++)
1978 new_string
+= toupper(*c
);
1980 return new(allocator
) string_const(new_string
);
1983 node
*builtin_str_startswith(context
*globals
, context
*ctx
, tuple
*args
, dict
*kwargs
) {
1984 NO_KWARGS_N_ARGS("str.startswith", 2);
1985 node
*self
= args
->__getitem__(0);
1986 node
*prefix
= args
->__getitem__(1);
1987 if (!self
->is_string() || !prefix
->is_string())
1988 error("bad arguments to str.startswith()");
1990 std::string s1
= self
->string_value();
1991 std::string s2
= prefix
->string_value();
1992 return create_bool_const(s1
.compare(0, s2
.size(), s2
) == 0);
1995 #define BUILTIN_FUNCTION(name) builtin_function_def builtin_function_##name(#name, builtin_##name);
1996 LIST_BUILTIN_FUNCTIONS(BUILTIN_FUNCTION
)
1997 #undef BUILTIN_FUNCTION
1999 void init_context(context
*ctx
, int_t argc
, char **argv
) {
2000 #define BUILTIN_FUNCTION(name) ctx->store(sym_id_##name, &builtin_function_##name);
2001 LIST_BUILTIN_FUNCTIONS(BUILTIN_FUNCTION
)
2002 #undef BUILTIN_FUNCTION
2004 #define BUILTIN_CLASS(name) ctx->store(sym_id_##name, &builtin_class_##name);
2005 LIST_BUILTIN_CLASSES(BUILTIN_CLASS
)
2006 #undef BUILTIN_CLASS
2008 ctx
->store(sym_id___name__
, new(allocator
) string_const("__main__"));
2009 list
*plist
= new(allocator
) list();
2010 for (int_t a
= 0; a
< argc
; a
++)
2011 plist
->append(new(allocator
) string_const(argv
[a
]));
2012 ctx
->store(sym_id___args__
, plist
);
2015 void collect_garbage(context
*ctx
, node
*ret_val
) {
2016 static int gc_tick
= 0;
2017 if (++gc_tick
> 128) {
2020 allocator
->mark_dead();
2022 ctx
->mark_live(ret_val
!= NULL
);
2025 ret_val
->mark_live();