Jump to content

Create an executable for a program in an interpreted language: Difference between revisions

→‎{{header|Wren}}: Now embeds the Wren source code in the C program itself.
(→‎{{header|Wren}}: Now embeds the Wren source code in the C program itself.)
Line 351:
 
=={{header|Wren}}==
 
{{improve|Wren|The task was intended to be to create an executable that would run one specific program (like you would get by compiling a program in a compiled language), not a general interpreter.<br>Sorry it was a bit confusing, I hope the revisions (and name change) make it a bit clearer.<br>Hopefully, the changes required won't be large... The Wren VM sounds pretty impressive, BTW}}
 
Wren source code is always compiled first into an intermediate bytecode using a single-pass compiler which is part of its virtual machine (VM). The VM then interprets the bytecode at runtime with respect to the underlying platform which can be Linux, MacOS, Windows or (in theory at least) anything else for which a standard C99 compiler is available.
Line 360 ⟶ 358:
Wren is designed for embedding and, technically, even ''Wren-cli'' - which enables Wren scripts to be run from the command line - is just a host application for the Wren VM which uses the cross-platform library, ''libuv'', to provide additional functionality (mainly I/O) not provided by Wren's standard library itself.
 
If we don't need this additional functionality, we can instead write a simple C host, link it to the Wren VM library and then use the latter to compile and run asome Wren source code filewhich we can embed in the C program itself. In fact, the VM is so small that its source could also be embedded directly into the C host as could the Wren source itself but, in the interests of tidiness and versatility,though we won't do that here.
 
So thisthe following C program (countdown.c) is perhaps the nearest we can get to the spirit of this task. The following C program (''wrenc.c'') could be used:
 
<lang C>#include <stdio.h>
<lang C>/* gcc -O3 wrenc.c -o wrenc -lwren -lm */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wren.h"
 
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
 
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
size_t ret = fread(script, 1, fsize, f);
if (!ret) perror("Error reading wren source file.");
fclose(f);
script[fsize] = 0;
return script;
}
 
static void loadModuleComplete(WrenVM* vm, const char* module, WrenLoadModuleResult result) {
if( result.source) free((void*)result.source);
}
 
WrenLoadModuleResult loadModule(WrenVM* vm, const char* name) {
WrenLoadModuleResult result = {0};
if (strcmp(name, "random") != 0 && strcmp(name, "meta") != 0) {
result.onComplete = loadModuleComplete;
char fullName[strlen(name) + 6];
strcpy(fullName, name);
strcat(fullName, ".wren");
result.source = readFile(fullName);
}
return result;
}
 
int main(int argc, char **argv) {
if (argc != 2) {
printf("Please pass the name of the Wren file to be executed.\n");
return 1;
}
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.loadModuleFn = &loadModule;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
char *script = "for (i in 5..0) System.print(i)"; /* Wren source code */
const char* fileName = argv[1];
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
wrenFreeVM(vm);
free(script);
return 0;
}</lang>
 
weWe can now compile this code (using GCC on Linux) and run it, and obtainobtaining the expected output (on Linux) as follows:
If we now create a Wren source code file: ''countdown.wren'':
<lang ecmascript>for (i in 5..0) System.print(i)</lang>
 
we can compile and run it and obtain the expected output (on Linux) as follows:
{{out}}
<pre>
$./wrenc gcc countdown.wrenc -o countdown -lwren -lm
$./countdown
5
4
9,485

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.