flat assembler
Message board for the users of flat assembler.

Index > Main > How to properly invoke FlatAssembler from an external progra

Author
Thread Post new topic Reply to topic
UniverseIsASimulation



Joined: 23 Sep 2016
Posts: 34
UniverseIsASimulation 17 Apr 2020, 17:37
So, I've made a compiler for my own simplified low-level programming language, the source code is available here, and the executable files are available here. Now, the compiler, "aec.exe" or "aec.c" produces assembly code that can be compiled with FlatAssembler, however, it can't invoke FlatAssembler even if it's installed. The compiler itself is written in JavaScript, in the files "compiler.js" and "compiler.js", and "aec.c" mainly initializes Duktape (the JavaScript engine written in C). So, here is the contents of the "aec.c" file (compiled into "aec.exe" executable):
Code:
#include <stdio.h>
#include <string.h>
#include "duktape.h"
#include "tcc-patch.h"


void handle_fatal(void *udata,const char *msg)
{
    fprintf(stderr,"Fatal error in Javascript: %s\n",(msg?msg:"no message"));
    exit(1);
}

void catch(void *ctx)
{
    fprintf(stderr,"JavaScript reports the following error:\n\"%s\"\n",duk_safe_to_string(ctx,-1));
    duk_destroy_heap(ctx);
    exit(1);
}

int main(int argc, char **argv)
{
    if (argc-2 or strlen(argv[1])<5 or (strcmp(argv[1]+strlen(argv[1])-4,".AEC") and strcmp(argv[1]+strlen(argv[1])-4,".aec")))
    {
        fprintf(stderr,"Please invoke this program from command-line and supply an AEC source file as the only argument, for example:\n"
                "Windows: aec.exe euclid.aec\n"
                "Linux and MacOS: ./aec euclid.aec\n");
        return 1;
    }
#include "readCompiler.h"
    input=fopen("control.js","r");
    if (!input)
    {
        fprintf(stderr,"Can't open 'control.js'?!\n");
        fflush(stderr);
        return 1;
    }
    while (!feof(input))
        if (fscanf(input,"%[^\n]\n",line)){
            strcat(line,"\n");
            strcat(compilerString,line);
        }
    fclose(input);
    fprintf(stderr,"Initializing Duktape!\n");
    fflush(stderr);
    duk_context *ctx=duk_create_heap(0,0,0,0,handle_fatal);
    duk_push_c_function(ctx,getIEEE754,1);
    duk_put_global_string(ctx,"getIEEE754");
    duk_eval_string(ctx,compilerString);
    free(compilerString),free(line);
    duk_set_top(ctx,1);
    fprintf(stderr,"Compilation started!\n");
    fflush(stderr);
    input=fopen(argv[1],"r");
    if (!input)
    {
        fprintf(stderr,"Can't read \'%s\'!\n",argv[1]);
        fflush(stderr);
        return 1;
    }
    int lineNumber=0;
    line=calloc(512,1);
    int hasError=0;
    compilerString=calloc(1024,1);
    if (!compilerString or !line)
    {
        fprintf(stderr,"Out of memory!?\n");
        return 1;
    }
    while (!feof(input)) {
        lineNumber++;
        if (fgets(line,512,input))
        {
            if (line[strlen(line)-1]=='\n') line[strlen(line)-1]=0;
            if (line[strlen(line)-1]=='\r') line[strlen(line)-1]=0;
            memset(compilerString,0,512);
            strcat(compilerString,"compileString(\"");
            int i;
                        for (i=0; line[i]; i++)
                if (line[i]=='\\')
                    strcat(compilerString,"\\\\");
                else if (line[i]=='"')
                    strcat(compilerString,"\\\"");
                else
                    strncat(compilerString,line+i,1);
            strcat(compilerString,"\")");
            duk_push_string(ctx,compilerString);
            if (duk_peval(ctx))
            {
                const char *message=duk_safe_to_string(ctx,-1);
                if (strstr(message,"error")) hasError=1;
                fprintf(stderr,"Message on line %d:\n\"%s\"\n",lineNumber,message);
            }
            duk_pop(ctx);
        }
    }
    free(line);
    free(compilerString);
    fclose(input);
    if (!hasError) {
        duk_eval_string(ctx,"stack.length");
        if (duk_get_int(ctx,-1))
        {
            fprintf(stderr,"Control structures ('If', 'Else', 'While', 'EndIf' and 'EndWhile') appear not to be properly nested, compilation aborted!\n");
            fflush(stderr);
            return 1;
        }
        char *outputFileName=calloc(265,1);
        strncat(outputFileName,argv[1],strlen(argv[1])-4);
        strcat(outputFileName,".asm");
        FILE *output=fopen(outputFileName,"w");
        free(outputFileName);
        if (!output)
        {
            fprintf(stderr,"Can't open output file!\n");
            fflush(stderr);
            return 1;
        }
        duk_eval_string(ctx,"assembler");
        fprintf(output,";Generated by Arithmetic Expression Compiler (https://flatassembler.github.io/compiler.html) run in Duktape.\n"
                "%s",duk_get_string(ctx,-1));
        fclose(output);
        fprintf(stderr,"Compilation finished without errors!\n");
    }
    else
        fprintf(stderr,"Compilation aborted due to the errors reported by JavaScript!\n");
    duk_destroy_heap(ctx);
    return 0;
}    
So, how would you modify it to invoke FlatAssembler? And checking whether FlatAssembler is in %PATH% and doing system("fasm assembly_language_file.asm") doesn't work, because then FlatAssembler reports it can't find "win32ax.inc" and other include files.
Post 17 Apr 2020, 17:37
View user's profile Send private message Reply with quote
UniverseIsASimulation



Joined: 23 Sep 2016
Posts: 34
UniverseIsASimulation 20 Apr 2020, 10:56
I think that the fact that there is no obvious way to invoke FlatAssembler from an external program to compile assembly is a major reason why FlatAssembler is so rarely used as a back-end. It's nice to have all these options in the user-friendly IDE, but they are worth little if external programs can't even invoke FASM to compile a program that compiles with default settings in the IDE, yet alone use all those options available in the IDE.
Post 20 Apr 2020, 10:56
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8357
Location: Kraków, Poland
Tomasz Grysztar 20 Apr 2020, 12:23
The required setup of INCLUDE environment variable is documented in section 1.1.1 of FASM.PDF.
Post 20 Apr 2020, 12:23
View user's profile Send private message Visit poster's website Reply with quote
UniverseIsASimulation



Joined: 23 Sep 2016
Posts: 34
UniverseIsASimulation 20 Apr 2020, 15:00
Tomasz Grysztar wrote:
The required setup of INCLUDE environment variable is documented in section 1.1.1 of FASM.PDF.
OK, I missed that, and it helps a little. It's not included in the documentation on the web.
So, how would you go about invoking FlatAssembler from an external program? Would you first check whether it's present in $path with system("fasm > nul")? If it is, then what? Somehow list all files in all the folders in $path to see in which "fasm.exe" is present, and then do "setenv" to add that folder plus "/include/" into $include, and then finally do system("fasm assembly.asm")? Or do you need to do something more?
Post 20 Apr 2020, 15:00
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 20 Apr 2020, 17:27
UniverseIsASimulation wrote:
OK, I missed that, and it helps a little. It's not included in the documentation on the web.

What about this? https://flatassembler.net/docs.php?article=manual#2.3.1
Post 20 Apr 2020, 17:27
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.