Permalink
Browse files

Removed new keyword/syntax in favor of python-style class() instancing

  • Loading branch information...
1 parent fa9deb0 commit dab85112d461516571b3ecabd2eb7f586a60daf5 @nardo committed Nov 22, 2009
Showing with 40 additions and 88 deletions.
  1. +0 −17 interpreter/kt_compiler.py
  2. +33 −38 interpreter/kt_vm.py
  3. +0 −1 parser/lexical_analyzer.flex
  4. +3 −30 parser/parser.bison
  5. +4 −2 test/test3/inheritance_test.kt
@@ -902,23 +902,6 @@ def _analyze_expr_map_expr(self, si, expr, valid_types, is_lvalue):
def _compile_expr_map_expr(self, si, expr, valid_types, is_lvalue):
return ('map', [(self.compile_expression(si, pair['key'], ('any'), False), self.compile_expression(si, pair['value'], ('any'), False)) for pair in expr['map_pairs']])
-
- def _analyze_expr_new_object_expr(self, si, expr, valid_types, is_lvalue):
- if is_lvalue:
- raise compile_error, (expr, "new expression cannot be an lvalue.")
- # search the global container
- node = self.find_node(si.compound_node, expr['parent_name'])
- if not node:
- raise compile_error, (expr, "locator " + locator_name + " not found.")
- expr['location'] = ('global_node', node)
- if not (node.type == 'class' or node.type == 'struct'):
- raise compile_error, (expr, "new only allowed for classes and structs.")
- for arg in expr['argument_expr_list']:
- self.analyze_expression(si, arg, ('any'), False)
-
- def _compile_expr_new_object_expr(self, si, expr, valid_types, is_lvalue):
- return ('new', expr['location'], [self.compile_expression(si, arg, ('any'), False) for arg in expr['argument_expr_list']])
-
View
@@ -21,6 +21,11 @@ def __init__(self, vm, error_string):
self.error_string = error_string
class vm:
+ class function_record_instance:
+ def __init__(self, record):
+ self.function_record = record
+ def call(self, vm, reference_object, parameters):
+ vm.invoke_function_record(self.function_record, reference_object, parameters)
class object_instance:
def __init__(self, node):
self.id = node.compound_record
@@ -32,18 +37,28 @@ def __init__(self, node):
self.node = node
self.compound_record = node.compound_record
def eval(self, vm):
- return self
+ return (self, None)
+ def call(self, vm, reference_object, params):
+ result = vm.object_instance(self.node)
+ if self.node.constructor_index is not None:
+ vm.invoke_function_record(vm.image.functions[self.node.constructor_index], result, params)
+ vm.return_value = result
+
class function_instance:
def __init__(self, node):
self.func_record = node.func_record
self.container_index = node.container.global_index
def eval(self, vm):
- return ('func_rec', self.func_record, vm.globals[self.container_index])
+ return (self, vm.globals[self.container_index])
+ def call(self, vm, reference_object, params):
+ return vm.invoke_function_record(self.func_record, reference_object, params)
class python_function_instance:
def __init__(self, node):
self.python_function = node.python_function
def eval(self, vm):
- return ('py_func', self.python_function)
+ return (self, None)
+ def call(self, vm, reference_object, params):
+ self.python_function(*params)
class python_class_instance:
def __init__(self, node):
self.python_class = node.python_class
@@ -82,26 +97,24 @@ def __init__(self, compiled_image):
self.return_value = None
for o in (o for o in compiled_image.globals_list if o.type == 'object'):
if o.constructor_index is not None:
- callable = ('func_rec', compiled_image.functions[o.constructor_index], self.globals[o.global_index])
+ callable = (vm.function_record_instance(compiled_image.functions[o.constructor_index]), self.globals[o.global_index])
self.call_function(callable, ())
def exec_function(self, func_name, args):
func_node = self.image.find_node(None, func_name, lambda x: x.type =='function' )
self.call_function(self.globals[func_node.global_index].eval(self), ())
- def call_function(self, callable, arguments):
- if callable[0] == 'func_rec':
- function_record = callable[1]
- reference_object = callable[2]
- new_frame = vm.frame(function_record, arguments, self.tos, reference_object)
- self.tos = new_frame
+ def invoke_function_record(self, function_record, reference_object, arguments):
+ new_frame = vm.frame(function_record, arguments, self.tos, reference_object)
+ self.tos = new_frame
+ result = self.exec_current_instruction()
+ while result == Exec_Normal:
result = self.exec_current_instruction()
- while result == Exec_Normal:
- result = self.exec_current_instruction()
- self.tos = self.tos.prev_frame
- return result
- elif callable[0] == 'py_func':
- callable[1](*arguments)
+ self.tos = self.tos.prev_frame
+ return result
+
+ def call_function(self, callable, arguments):
+ callable[0].call(self, callable[1], arguments)
def exec_current_instruction(self):
instruction = self.tos.function_record.statements[self.tos.ip]
@@ -236,7 +249,7 @@ def _eval_global_node(self, node):
return self.globals[node.global_index].eval(self)
def _eval_sub_function(self, sub_function_index):
# callables are (function_record, reference_object) pairs
- return ('func_rec', self.image.functions[sub_function_index], self.tos)
+ return (vm.function_record_instance(self.image.functions[sub_function_index]), self.tos)
def _eval_string_constant(self, value):
return value
def _eval_int_constant(self, value):
@@ -266,11 +279,11 @@ def _eval_imethod(self, imethod_index):
reference_object = self.tos.reference_object
method = reference_object.id.vtable[imethod_index]
spew("imethod: " + str(reference_object))
- return ('func_rec', method, reference_object)
+ return (vm.function_record_instance(method), reference_object)
def _eval_selfmethod_global(self, global_index):
reference_object = self.tos.reference_object
method = self.image.functions[global_index]
- return ('func_rec', method, reference_object)
+ return (vm.function_record_instance(method), reference_object)
def _eval_ivar(self, ivar_index):
return self.tos.reference_object.slots[ivar_index]
@@ -283,7 +296,7 @@ def _eval_slot(self, object_expr, slot_name):
if the_slot.type == 'variable':
return the_object.slots[the_slot.index]
elif the_slot.type == 'function':
- return ('func_rec', the_object.id.vtable[the_slot.index], the_object)
+ return (vm.function_record_instance(the_object.id.vtable[the_slot.index]), the_object)
#conditional_expr
# test_expression
@@ -319,24 +332,6 @@ def _eval_map(self, map_pairs_list):
value = self.eval(pair[1])
result[key] = value
return result
- #new_object_expr
- # parent_name
- # argument_expr_list
-
- def _eval_new(self, class_node, args):
- cnode = self.eval(class_node)
- result = vm.object_instance(cnode.node)
- evaluated_args = [self.eval(arg) for arg in args]
- if cnode.node.constructor_index is not None:
- callable = ('func_rec', self.image.functions[cnode.node.constructor_index], result)
- self.call_function(callable, evaluated_args)
- return result
-
-
- #new_object_expr_type_expr
- # parent_name_expr
- # argument_expr_list
-
#('prev_scope', ()) - a reference to a variable in a previous scope
#('local', local_index) - local variable
@@ -459,7 +459,6 @@ COMMENT "//"[^\n\r]*
"switch" return rwSWITCH;
"case" return rwCASE;
"default" return rwDEFAULT;
-"new" return rwNEW;
"var" return rwVAR;
"file" return rwFILE;
View
@@ -63,7 +63,6 @@ void kt_error (struct YYLTYPE *loc, kt_lexer *lexer, parse_result *result, const
%token rwSWITCH "switch"
%token rwCASE "case"
%token rwDEFAULT "default"
-%token rwNEW "new"
%token rwVAR "var"
%token rwINTEGER "integer"
%token rwFLOAT "float"
@@ -1076,15 +1075,14 @@ strcat_expression
}
;
-new_or_func_expression
+strcat_or_func_expression
: strcat_expression
- | new_expression
| function_expression
;
conditional_expression
- : new_or_func_expression
- | new_or_func_expression '?' expression ':' conditional_expression
+ : strcat_or_func_expression
+ | strcat_or_func_expression '?' expression ':' conditional_expression
{
$$ = node(conditional_expr);
field($$, test_expression, $1);
@@ -1220,31 +1218,6 @@ function_expression
}
;
-new_expression
- : "new" locator optional_argument_specifier
- {
- $$ = node(new_object_expr);
- field($$, parent_name, $2);
- field($$, argument_expr_list, $3);
- }
- | "new" '(' expression ')' optional_argument_specifier
- {
- $$ = node(new_object_expr_type_expr);
- field($$, parent_name_expr, $3);
- field($$, argument_expr_list, $5);
- }
- ;
-
-optional_argument_specifier
- :
- { $$ = empty_list(); }
- | '(' ')'
- { $$ = empty_list(); }
- | '(' argument_expression_list ')'
- { $$ = $2; }
- ;
-
-
%%
void kt_error (struct YYLTYPE *loc, kt_lexer *lexer, parse_result *result, const char *format, ...)
@@ -37,5 +37,7 @@ function main()
'container/sub_object2'.do_print()
sub_object2.do_print()
'container2/sub_object2'.do_print()
- var object3 = new test_subclass(100, 200)
- object3.do_print()
+ //var object3 = new test_subclass(100, 200)
+ //object3.do_print()
+ var object4 = test_subclass("foo", "bar")
+ object4.do_print()

0 comments on commit dab8511

Please sign in to comment.