src: add phase.nit & frontend.nit
authorJean Privat <jean@pryen.org>
Fri, 19 Jul 2013 02:58:02 +0000 (22:58 -0400)
committerJean Privat <jean@pryen.org>
Fri, 19 Jul 2013 12:58:46 +0000 (08:58 -0400)
Also convert all phases of exprbuilder.nit

Signed-off-by: Jean Privat <jean@pryen.org>

13 files changed:
src/auto_super_init.nit
src/flow.nit
src/frontend.nit [new file with mode: 0644]
src/literal.nit
src/local_var_init.nit
src/modelbuilder.nit
src/nit.nit
src/nitg.nit
src/nitmetrics.nit
src/phase.nit [new file with mode: 0644]
src/scope.nit
src/simple_misc_analysis.nit
src/typing.nit

index d939740..b60ab85 100644 (file)
@@ -20,6 +20,16 @@ module auto_super_init
 
 import typing
 import modelbuilder
+import phase
+
+redef class ToolContext
+       var auto_super_init_phase: Phase = new AutoSuperInitPhase(self, [typing_phase])
+end
+
+private class AutoSuperInitPhase
+       super Phase
+       redef fun process_npropdef(npropdef) do if npropdef isa AConcreteMethPropdef then npropdef.do_auto_super_init(toolcontext.modelbuilder)
+end
 
 private class AutoSuperInitVisitor
        super Visitor
index e72ddbc..cdc5ece 100644 (file)
@@ -20,6 +20,17 @@ module flow
 import parser
 import toolcontext
 import scope
+import phase
+
+redef class ToolContext
+       var flow_phase: Phase = new FlowPhase(self, [scope_phase])
+end
+
+private class FlowPhase
+       super Phase
+
+       redef fun process_npropdef(npropdef) do npropdef.do_flow(toolcontext)
+end
 
 # The visitor that derermine flowcontext for nodes
 private class FlowVisitor
diff --git a/src/frontend.nit b/src/frontend.nit
new file mode 100644 (file)
index 0000000..f196f21
--- /dev/null
@@ -0,0 +1,37 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# 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.
+
+# Collect and orchestration of main frontend phases
+module frontend
+
+import phase
+import simple_misc_analysis
+import literal
+import scope
+import flow
+import local_var_init
+import typing
+import auto_super_init
+import div_by_zero
+
+redef class ToolContext
+       # FIXME: there is conflict in linex in nitc, so use this trick to force invocation
+       private var dummy: Bool = do_dummy
+       fun do_dummy: Bool
+       do
+               # Force easy warnings before intraproc-errors
+               phases.add_edge(scope_phase, simple_misc_analysis_phase)
+               return true
+       end
+end
index 5bb3f47..5d69035 100644 (file)
@@ -19,6 +19,19 @@ module literal
 
 import parser
 import toolcontext
+import phase
+
+import modelbuilder #FIXME useless
+
+redef class ToolContext
+       var literal_phase: Phase = new LiteralPhase(self, null)
+end
+
+private class LiteralPhase
+       super Phase
+
+       redef fun process_nmodule(nmodule) do nmodule.do_literal(toolcontext)
+end
 
 redef class AModule
        # Visit the module to compute the real value of the literal-related node of the AST.
index 0ef4b4a..cc389be 100644 (file)
@@ -20,6 +20,17 @@ module local_var_init
 
 import scope
 import flow
+import phase
+
+redef class ToolContext
+       var local_var_init_phase: Phase = new LocalVarInitPhase(self, [flow_phase])
+end
+
+private class LocalVarInitPhase
+       super Phase
+
+       redef fun process_npropdef(npropdef) do npropdef.do_local_var_init(toolcontext)
+end
 
 redef class APropdef
        # Entry point of the whole local variable initialization verifier
index 3025afe..f12fc5c 100644 (file)
@@ -27,6 +27,7 @@ import model
 import poset
 import opts
 import toolcontext
+import phase
 
 ###
 
@@ -60,6 +61,17 @@ class ModelBuilder
        # The toolcontext used to control the interaction with the user (getting options and displaying messages)
        var toolcontext: ToolContext
 
+       fun run_phases
+       do
+               var mmodules = model.mmodules.to_a
+               model.mmodule_importation_hierarchy.sort(mmodules)
+               var nmodules = new Array[AModule]
+               for mm in mmodules do
+                       nmodules.add(mmodule2nmodule[mm])
+               end
+               toolcontext.run_phases(nmodules)
+       end
+
        # Instantiate a modelbuilder for a model and a toolcontext
        # Important, the options of the toolcontext must be correctly set (parse_option already called)
        init(model: Model, toolcontext: ToolContext)
index eedb11d..981a85c 100644 (file)
@@ -18,7 +18,7 @@
 module nit
 
 import modelbuilder
-import exprbuilder
+import frontend
 import naive_interpreter
 import debugger
 #import interpretor_type_test
@@ -45,7 +45,7 @@ var progname = arguments.first
 
 # Here we load an process all modules passed on the command line
 var mmodules = modelbuilder.parse_and_build([progname])
-modelbuilder.full_propdef_semantic_analysis
+modelbuilder.run_phases
 
 if toolcontext.opt_only_metamodel.value then exit(0)
 
index fbb09c2..ed84e7c 100644 (file)
@@ -18,7 +18,7 @@
 module nitg
 
 import modelbuilder
-import exprbuilder
+import frontend
 import rapid_type_analysis
 import global_compiler
 import separate_erasure_compiler
@@ -49,7 +49,7 @@ var progname = arguments.first
 # Here we load an process all modules passed on the command line
 var mmodules = modelbuilder.parse_and_build([progname])
 if mmodules.is_empty then return
-modelbuilder.full_propdef_semantic_analysis
+modelbuilder.run_phases
 
 if toolcontext.opt_only_metamodel.value then exit(0)
 
index 561d84c..1d5bfde 100644 (file)
@@ -18,7 +18,7 @@
 module nitmetrics
 
 import modelbuilder
-import exprbuilder
+import frontend
 import metrics
 
 # Create a tool context to handle options and paths
@@ -40,7 +40,7 @@ var modelbuilder = new ModelBuilder(model, toolcontext)
 
 # Here we load an process all modules passed on the command line
 var mmodules = modelbuilder.parse_and_build(arguments)
-modelbuilder.full_propdef_semantic_analysis
+modelbuilder.run_phases
 
 if mmodules.length == 0 then return
 
diff --git a/src/phase.nit b/src/phase.nit
new file mode 100644 (file)
index 0000000..667ba43
--- /dev/null
@@ -0,0 +1,105 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# 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.
+
+# Phases of the processing of nit programs
+module phase
+
+import toolcontext
+import parser
+import poset
+
+redef class ToolContext
+       # The various registered phases to performs
+       # The order in the poset is the dependance of phases
+       #
+       # While you can directly modify the poset (nodes and edges),
+       # it is often simpler to use the constructor in `Phase`
+       var phases = new POSet[Phase]
+
+       # Run all registered phases on a set of modules
+       fun run_phases(nmodules: Collection[AModule])
+       do
+               var time0 = get_time
+               self.info("*** SEMANTIC ANALYSIS ***", 1)
+               #phases.show_dot
+               var phases = self.phases.to_a
+               self.phases.sort(phases)
+
+               for phase in phases do
+                       self.info(" registered phases: {phase.class_name}", 2)
+               end
+
+               for nmodule in nmodules do
+                       self.info("Semantic analysis module {nmodule.location.file.filename}", 2)
+                       for phase in phases do
+                               self.info(" phase: {phase.class_name}", 3)
+                               assert phase.toolcontext == self
+                               var errcount = self.error_count
+                               phase.process_nmodule(nmodule)
+                               if errcount != self.error_count then
+                                       self.check_errors
+                                       break
+                               end
+                               errcount = self.error_count
+                               for nclassdef in nmodule.n_classdefs do
+                                       for npropdef in nclassdef.n_propdefs do
+                                               self.info(" phase: {phase.class_name} for {npropdef.location}", 4)
+                                               assert phase.toolcontext == self
+                                               phase.process_npropdef(npropdef)
+                                       end
+                               end
+                               if errcount != self.error_count then
+                                       self.check_errors
+                                       break
+                               end
+                       end
+                       self.check_errors
+               end
+
+               var time1 = get_time
+               self.info("*** END SEMANTIC ANALYSIS: {time1-time0} ***", 2)
+       end
+end
+
+# Abstraction of steps in the analysis/processing of Nit programs
+# Specific phases should implements either `process_nmodule` or
+# `process_npropdef`.
+abstract class Phase
+       # The toolcontext instance attached to the phase
+       var toolcontext: ToolContext
+
+       # The dependence relation of the phase with the other phases
+       var in_hierarchy: POSetElement[Phase]
+
+       # Initialize and register a phase to the toolcontext
+       init(toolcontext: ToolContext, depends: nullable Collection[Phase])
+       do
+               self.toolcontext = toolcontext
+               in_hierarchy = toolcontext.phases.add_node(self)
+               if depends != null then
+                       for d in depends do
+                               toolcontext.phases.add_edge(self, d)
+                       end
+               end
+       end
+
+       # Specific actions to execute on the whole tree of a module
+       # @toimplement
+       fun process_nmodule(nmodule: AModule) do end
+
+       # Specific actions to execute on the tree of a property
+       # Note that the order of the visit is the one of the file
+       # @toimplement
+       fun process_npropdef(npropdef: APropdef) do end
+end
index 8a90c3f..5197c19 100644 (file)
@@ -19,6 +19,19 @@ module scope
 
 import parser
 import toolcontext
+import phase
+
+import modelbuilder #FIXME useless
+
+redef class ToolContext
+       var scope_phase: Phase = new ScopePhase(self, null)
+end
+
+private class ScopePhase
+       super Phase
+       redef fun process_npropdef(npropdef) do npropdef.do_scope(toolcontext)
+end
+
 
 # A local variable (including parameters, automatic variables and self)
 class Variable
index bc6c945..c5ec019 100644 (file)
@@ -23,6 +23,18 @@ package simple_misc_analysis
 
 import toolcontext
 import parser
+import phase
+
+import modelbuilder #FIXME useless
+
+redef class ToolContext
+       var simple_misc_analysis_phase: Phase = new SimpleMiscAnalysisPhase(self, null)
+end
+
+private class SimpleMiscAnalysisPhase
+       super Phase
+       redef fun process_nmodule(nmodule) do nmodule.do_simple_misc_analysis(toolcontext)
+end
 
 redef class AModule
        # Visit the module to detect easy warnings that does not need the metamodel or the importation
index c1720c1..9510a61 100644 (file)
@@ -20,6 +20,17 @@ module typing
 
 import flow
 import modelbuilder
+import phase
+import local_var_init
+
+redef class ToolContext
+       var typing_phase: Phase = new TypingPhase(self, [flow_phase, local_var_init_phase])
+end
+
+private class TypingPhase
+       super Phase
+       redef fun process_npropdef(npropdef) do npropdef.do_typing(toolcontext.modelbuilder)
+end
 
 private class TypeVisitor
        var modelbuilder:  ModelBuilder