From 9071c37d7f66dd38772b5203610f6e3b0008c069 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Julien=20Pag=C3=A8s?= Date: Tue, 10 Feb 2015 17:08:19 +0100 Subject: [PATCH] nitvm: The local variables are numbered MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The access to them is made by their position in this array Signed-off-by: Julien Pagès --- src/nit.nit | 1 + src/nitvm.nit | 1 + src/variables_numbering.nit | 223 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 src/variables_numbering.nit diff --git a/src/nit.nit b/src/nit.nit index 8be9ae2..13f8c59 100644 --- a/src/nit.nit +++ b/src/nit.nit @@ -22,6 +22,7 @@ import frontend import parser_util import vm import vm_optimizations +import variables_numbering # Create a tool context to handle options and paths var toolcontext = new ToolContext diff --git a/src/nitvm.nit b/src/nitvm.nit index 5e5dde3..1fef7a4 100644 --- a/src/nitvm.nit +++ b/src/nitvm.nit @@ -19,6 +19,7 @@ module nitvm import vm import vm_optimizations +import variables_numbering import frontend # Create a tool context to handle options and paths diff --git a/src/variables_numbering.nit b/src/variables_numbering.nit new file mode 100644 index 0000000..7698ad2 --- /dev/null +++ b/src/variables_numbering.nit @@ -0,0 +1,223 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2015 Julien Pagès +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Handle all numbering operations related to local variables in the Nit virtual machine +module variables_numbering + +import vm + +redef class VirtualMachine + + # Number the variables in `n`. + # Do nothing if `n` is null + fun numbering(n: nullable AExpr, position: Int): Int + do + if n == null then return position + + var pos = n.numbering(self, position) + return pos + end +end + +redef class Variable + # The position in the environment + var position: Int +end + +redef class AExpr + # Give a position to each variable declared in the node. + # NOTE: Do not call this method directly, but use `v.numbering` + # This method is here to be implemented by subclasses. + # *`v` The current instance of the virtual machine + # *`position` The first available position in the environment a variable can have + # Return the next available position a variable can have + public fun numbering(v: VirtualMachine, position: Int): Int + do + return position + end +end + +redef class APropdef + # Indicate if the variables numbering has been done + private var is_numbering: Bool = false + + # The size of the environment to create to call this method + private var environment_size: Int = 0 +end + +redef class AMethPropdef + # Assign a position in the environment to each local variable of `mpropdef` + # *`v` The current VirtualMachine + # *`mpropdef` The method to number + private fun numbering_variables(v: VirtualMachine, mpropdef: MMethodDef) + do + # The position in the environment + var position = 0 + + # The `self` variable has the first position + if self.selfvariable != null then + self.selfvariable.position = position + position += 1 + end + + # Number the parameters + for i in [0..mpropdef.msignature.arity[ do + var variable = self.n_signature.n_params[i].variable + variable.as(not null).position = position + position += 1 + end + + # Recursively go into the AST nodes to number all local variables + if n_block != null then + position = v.numbering(self.n_block, position) + end + + is_numbering = true + + # The size of the environment to create to execute a call to this method + environment_size = position + end +end + +redef class AAttrPropdef + # Assign a position in the environment to each local variable of `mpropdef` + # *`v` The current VirtualMachine + private fun numbering_variables(v: VirtualMachine) + do + # The position in the environment + var position = 0 + + # The `self` variable has the first position + if self.selfvariable != null then + self.selfvariable.position = position + position += 1 + end + + # Recursively go into the AST nodes to number all local variables + if n_block != null then + position = v.numbering(self.n_block, position) + end + + is_numbering = true + + # The size of the environment to create to execute a call to this method + environment_size = position + end +end + +redef class AVardeclExpr + redef fun numbering(v, position) + do + # Attribute a position to this variable + self.variable.as(not null).position = position + position += 1 + + # Recursively continue to numbering the variables + position = v.numbering(self.n_expr, position) + + # `position` is the next available position in the environment + return position + end +end + +redef class ABlockExpr + redef fun numbering(v, position) + do + for e in self.n_expr do + position = v.numbering(e, position) + end + return position + end +end + +redef class AIfExpr + redef fun numbering(v, position) + do + # Attribute numbers separetely for the two branches + var pos = v.numbering(self.n_then, position) + var pos1 = v.numbering(self.n_else, position) + + if pos > pos1 then + return pos + else + return pos1 + end + end +end + +redef class AIfexprExpr + redef fun numbering(v, position) + do + # Attribute numbers separetely for the two branches + var pos = v.numbering(self.n_then, position) + var pos1 = v.numbering(self.n_else, position) + + if pos > pos1 then + return pos + else + return pos1 + end + end +end + +redef class ADoExpr + redef fun numbering(v, position) + do + return v.numbering(self.n_block, position) + end +end + +redef class AWhileExpr + redef fun numbering(v, position) + do + return v.numbering(self.n_block, position) + end +end + +redef class ALoopExpr + redef fun numbering(v, position) + do + return v.numbering(self.n_block, position) + end +end + +redef class AForExpr + redef fun numbering(v, position) + do + # Give a position to each variable declared in the header of the for + if self.variables.length == 1 then + self.variables.first.position = position + self.variables[0].position = position + position += 1 + else if self.variables.length == 2 then + self.variables[0].position = position + position += 1 + self.variables[1].position = position + position += 1 + end + return v.numbering(self.n_block, position) + end +end + +redef class AArrayExpr + redef fun numbering(v, position) + do + for nexpr in self.n_exprs do + position = v.numbering(nexpr, position) + end + return position + end +end -- 1.7.9.5