Compiler/Simple file inclusion pre processor: Difference between revisions

Content added Content deleted
(→‎{{header|Wren}}: Revised following latest clarification.)
Line 601: Line 601:
=={{header|Wren}}==
=={{header|Wren}}==


Wren already implements file inclusion via its '''import''' statement which can appear anywhere that a variable declaration can, including within a block, and can therefore be subject to a condition.
I'm not really sure how this task relates to languages such as Wren which (despite limited compilation) are basically interpreters so, despite what it says in the task description, I'll confine this entry to describing the situation.


Any number of files can be imported in this way and can contain any Wren source code including other '''import''' statements to any level of nesting. However, Wren's virtual machine (VM) keeps track of the imported files and will only load a particular file once.
Wren already implements file inclusion via its '''''import''''' statement which can appear anywhere that a variable declaration can, including within a block, and can therefore be subject to a condition.

Any number of files can be imported in this way and can contain any Wren source code including other '''''import''''' statements to any level of nesting. However, Wren's virtual machine (VM) keeps track of the imported files and will only load a particular file once.


All the modules listed on the language's main page need to be imported in this way.
All the modules listed on the language's main page need to be imported in this way.
Line 614: Line 612:


It will therefore be seen that Wren neither has nor needs a pre-processor; it doesn't support macros or other text substitution devices and imports are always in source code rather than binary form.
It will therefore be seen that Wren neither has nor needs a pre-processor; it doesn't support macros or other text substitution devices and imports are always in source code rather than binary form.

Nevertheless, it is possible to write a limited pre-processor in Wren (the VM itself is written in C):
<lang ecmascript>import "io" for File

var source = File.read("source.wren")

var ix
var start = 0
while ((ix = source.indexOf("import", start)) && ix >= 0) {
var ix2 = source.indexOf("\n", ix + 6)
if (ix2 == -1) ix2 = source.count
start = ix + 1
var imp = source[ix...ix2]
var tokens = imp.split(" ").where { |s| s != "" }.toList
var filePath = tokens[1][1...-1]
if (filePath.startsWith("./")) {
filePath = filePath[2..-1]
} else if (filePath.startsWith("/")) {
filePath = filePath[1..-1]
} else {
continue // leave resolution of other modules to compiler
}
var text = File.read(filePath + ".wren")
source = source[0...ix] + "\n%(text)\n" + source[ix2..-1]
}

File.create("source2.wren") { |file| file.writeBytes(source) }</lang>
<br>
The above code is limited in the sense that '''all''' top-level variables of the imported module (not just the specifically imported ones) are now visible in the outer scope. Consequently, the code will no longer compile if there are any name clashes.

The obvious solution of placing the imported code in a block and then 'lifting' the specifically imported variables into the outer scope does not work because of Wren's rather strange scoping rules. If you did this, then the imported module's top level variables would no longer be top-level relative to the code as a whole and hence would no longer be visible to classes defined within the module itself! For example, if you try to run the following script, you get the error shown:
<lang ecmascript>var B

{ // block starts here
var A = 2
class C {
static method1() {
System.print(A) // Error at 'A': Variable is used but not defined.
}
}

B = C
} // end of block

B.method()</lang>

Other problems include dealing with '''import''' statements which have been commented out (not catered for in the above pre-processor) and resolving import file paths which is not actually set in stone but depends on how Wren is being embedded. The above pre-processor code only deals with paths which are relative to the current directory.