Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the usability of ASTBuilder #2850

Merged
merged 6 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/astbuilder.nit
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ class ASTBuilder
return new AIntegerExpr.make(value, mmodule.int_type)
end

# Make a self expression
fun make_self: ASelfExpr
do
return new ASelfExpr
end

# Make a new instantiation
fun make_new(callsite: CallSite, args: nullable Array[AExpr]): ANewExpr
do
Expand Down
4 changes: 3 additions & 1 deletion src/contracts.nit
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ redef class AModule
# Entry point to generate the entire contract infrastructure.
# Once this method is called we must call the `do_weaving_contracts` method (see it for more information).
fun do_contracts(toolcontext: ToolContext) do
var ast_builder = new ASTBuilder(mmodule.as(not null))
var mmodule = self.mmodule
if mmodule == null then return # Skip errir
var ast_builder = new ASTBuilder(mmodule)
#
var contract_visitor = new ContractsVisitor(toolcontext, toolcontext.modelbuilder.identified_modules.first, self, ast_builder)
contract_visitor.enter_visit(self)
Expand Down
61 changes: 61 additions & 0 deletions src/examples/module_fictive.nit
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# 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.

# Sample program that show how to build (and run) a synthetic program from the AST builder
import nitc::astprinter
import nitc::interpreter
import nitc::astbuilder

# 3 god classes
var tc = new ToolContext
tc.keep_going = true
var model = new Model
var mb = new ModelBuilder(model, tc)

# load the code module. While implicit in source code, we need to retrieve it for synthetic code
var acore = mb.load_module("core")
var mcore = acore.mmodule
assert mcore != null
# Loading does not perform the analysis, so force the analysis now
mb.run_phases

# A synthetic main module
var mmodule = new MModule(model, null, "m0", model.no_location)
mmodule.set_imported_mmodules([mcore]) # Close the module hierarchy
mmodule.set_visibility_for(mcore, public_visibility) # Important, or else `_name` methods will fail

# Refine Sys in the main module
var mclass = mmodule.sys_type
assert mclass != null
var mclassdef = new MClassDef(mmodule, mclass, model.no_location)
mclassdef.add_in_hierarchy # Close the classdef hierarchy

# Redefine Sys::main
var nmeth = mb.create_method_from_name("main", mclassdef, false)

# Body is `self.print(42)`
var ab = new ASTBuilder(mmodule, mclass)
var narg = ab.make_int(42)
var nrecv = ab.make_self
var mprint = mb.try_get_mproperty_by_name2(null, mmodule, mclass, "print")
assert mprint isa MMethod
var callsite = ab.create_callsite(mprint, false)
var ncall = ab.make_call(nrecv, callsite, [narg])
nmeth.n_block.add(ncall)

nmeth.dump_tree(false, false)
ncall.print_tree

var interpreter = new NaiveInterpreter(mb, mmodule, new Array[String])
interpreter.start(mmodule)
42 changes: 42 additions & 0 deletions src/examples/module_injected.nit
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# 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.

# Sample program that show how to load (and run) a program from a String
module module_injected

import nitc::parser_util
import nitc::astprinter
import nitc::interpreter

# 3 god classes
var tc = new ToolContext
tc.keep_going = true
var model = new Model
var mb = new ModelBuilder(model, tc)

# Parse the module
var amodule = tc.parse_module("print 42")
# Add it to the model through the model builder
var mmodule = mb.load_rt_module(null, amodule, "-")
assert mmodule != null
# Do the semantic analysis
mb.run_phases

amodule.dump_tree
var main_method = amodule.n_classdefs.last.n_propdefs.first
main_method.print_tree
assert main_method isa AMethPropdef

var interpreter = new NaiveInterpreter(mb, mmodule, new Array[String])
interpreter.start(mmodule)
1 change: 1 addition & 0 deletions src/ffi/header_dependency.nit
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ private class HeaderDependancyPhase
redef fun process_nmodule(nmodule)
do
var mmodule = nmodule.mmodule
if mmodule == null then return # Skip error
mmodule.compute_header_dependencies(self)
end
end
4 changes: 2 additions & 2 deletions src/nit.nit
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ var mmodules: Array[MModule]

if opt_eval.value then
var amodule = toolcontext.parse_module(progname)
toolcontext.check_errors

var parent = null
if opt_loop.value then
Expand All @@ -62,13 +61,14 @@ if opt_eval.value then
end

modelbuilder.load_rt_module(parent, amodule, "-")
toolcontext.check_errors

mmodules = [amodule.mmodule.as(not null)]
else if progname == "-" then
var content = stdin.read_all
var amodule = toolcontext.parse_module(content)
toolcontext.check_errors
modelbuilder.load_rt_module(null, amodule, "-")
toolcontext.check_errors
mmodules = [amodule.mmodule.as(not null)]
else
mmodules = modelbuilder.parse([progname])
Expand Down
19 changes: 17 additions & 2 deletions src/parser/parser_nodes.nit
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ abstract class ANode
# However, manual instantiated nodes may need more care.
var location: Location is writable, noinit

fun has_location: Bool
do
return isset self._location
end

# The location of the important part of the node (identifier or whatever)
fun hot_location: Location do return location

Expand Down Expand Up @@ -235,7 +240,11 @@ class ASTDump

redef fun display(n)
do
return "{n.class_name} {n.dump_info(self)} @{n.location}"
if n.has_location then
return "{n.class_name} {n.dump_info(self)} @{n.location}"
else
return "{n.class_name} {n.dump_info(self)}"
end
end

# `s` as yellow
Expand Down Expand Up @@ -382,7 +391,13 @@ abstract class Token

redef fun is_structural do return true

redef fun dump_info(v) do return " {text.escape_to_c}"
redef fun dump_info(v) do
if has_location then
return " {text.escape_to_c}"
else
return ""
end
end

# Loose tokens that precede `self`.
#
Expand Down
11 changes: 8 additions & 3 deletions src/toolcontext.nit
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,8 @@ class ToolContext
opt_stub_man.hidden = true
opt_bash_completion.hidden = true
opt_set_dummy_tool.hidden = true

nit_dir = locate_nit_dir
end

# Name, usage and synopsis of the tool.
Expand Down Expand Up @@ -503,6 +505,10 @@ The Nit language documentation and the source code of its tools and libraries ma
end

nit_dir = locate_nit_dir
if nit_dir == null then
fatal_error(null, "Fatal Error: cannot locate a valid base Nit directory. It is quite unexpected. Try to set the environment variable `NIT_DIR` or to use the `--nit-dir` option.")
abort
end

if option_context.rest.is_empty and not accept_no_arguments then
print tooldescription
Expand Down Expand Up @@ -577,7 +583,7 @@ The Nit language documentation and the source code of its tools and libraries ma
#
# The result is returned without being assigned to `nit_dir`.
# This function is automatically called by `process_options`
fun locate_nit_dir: String
fun locate_nit_dir: nullable String
do
# the option has precedence
var res = opt_nit_dir.value
Expand Down Expand Up @@ -617,8 +623,7 @@ The Nit language documentation and the source code of its tools and libraries ma
if check_nit_dir(res) then return res.simplify_path
end

fatal_error(null, "Fatal Error: cannot locate a valid base Nit directory. It is quite unexpected. Try to set the environment variable `NIT_DIR` or to use the `--nit-dir` option.")
abort
return null
end

private fun check_nit_dir(res: String): Bool
Expand Down
2 changes: 2 additions & 0 deletions tests/nitcg.skip
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ get_mclasses
^nit
test_astbuilder
test_astprinter
module_fictive
module_injected
2 changes: 2 additions & 0 deletions tests/niti.skip
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@ nitpm
nitdoc
test_astbuilder
test_astprinter
module_fictive
module_injected
11 changes: 11 additions & 0 deletions tests/sav/module_fictive.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
AMethPropdef @
|--APublicVisibility
|--AIdMethid
|--ASignature
`--ABlockExpr
`--ACallExpr call=Sys.file$Sys$print(object: Object)
|--ASelfExpr
`--AListExprs
`--AIntegerExpr :Int
self.print(42)
42
14 changes: 14 additions & 0 deletions tests/sav/module_injected.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
1 print 42
AModule @1,1--8
`--AMainClassdef @1,1--8
`--AMainMethPropdef @1,1--8
`--ABlockExpr @1,1--8
`--ACallExpr call=Sys.file$Sys$print(object: Object) @1,1--8
|--AImplicitSelfExpr :Sys @1,1
|--AQid @1,1--5
| `--TId print @1,1--5
`--AListExprs @1,7--8
`--AIntegerExpr :Int @1,7--8
`--TInteger 42 @1,7--8
print(42)
42
Loading