shinh / elvm Goto Github PK
View Code? Open in Web Editor NEWEsoLangVM Compiler Infrastructure
License: MIT License
EsoLangVM Compiler Infrastructure
License: MIT License
Is there a way to build a single output from 2 files?
This project only supports Linux, so I have to copy it to a virtual machine to execute it, why not let it support Windows?
% make
Skip building js due to lack of nodejs
Skip building tex due to lack of tex
Skip building i due to lack of ick
out/8cc -S -I. -Ilibc -Iout out/24_cmp.c -o out/24_cmp.c.eir.tmp && mv out/24_cmp.c.eir.tmp out/24_cmp.c.eir
Usage: 8cc [ -E ][ -a ] [ -h ] <file>
-I<path> add to include path
-E print preprocessed source code
-D name Predefine name as a macro
-D name=def
-S Stop before assembly (default)
-c Do not run linker (default)
-U name Undefine name
-fdump-ast print AST
-fdump-stack Print stacktrace
-fno-dump-source Do not emit source code as assembly comment
-o filename Output to the specified file
-g Do nothing at this moment
-Wall Enable all warnings
-Werror Make all warnings into errors
-O<number> Does nothing at this moment
-m64 Output 64-bit code (default)
-w Disable all warnings
-h print this help
One of -a, -c, -E or -S must be specified.
make: *** [out/24_cmp.c.eir] Error 1
Github shows that there hasn't been any updates since October 13, 2022. Is this project still being maintained?
$ make rb
...
cp 8cc/*.h 8cc/*.inc 8cc/include/*.h out
cat 8cc/buffer.c 8cc/cpp.c 8cc/debug.c 8cc/dict.c 8cc/encoding.c 8cc/error.c 8cc/file.c 8cc/gen.c 8cc/lex.c 8cc/main.c 8cc/map.c 8cc/parse.c 8cc/path.c 8cc/set.c 8cc/vector.c > out/8cc.c.tmp && mv out/8cc.c.tmp out/8cc.c
out/8cc -S -I. -Ilibc -Iout out/8cc.c -o out/8cc.c.eir.tmp && mv out/8cc.c.eir.tmp out/8cc.c.eir
[ERROR] cpp.c:716: out/8cc.c:1713:1: cannot find header file: sys/stat.h
build.mk:5: recipe for target 'out/8cc.c.eir' failed
make: *** [out/8cc.c.eir] Error 1
$ touch libc/sys/stat.h
then passed.
I tried using 8cc in out/8cc to compile a c file but all I get when I run 8cc is
`Usage: 8cc [ -E ][ -a ] [ -h ]
-I add to include path
-E print preprocessed source code
-D name Predefine name as a macro
-D name=def
-S Stop before assembly (default)
-c Do not run linker (default)
-U name Undefine name
-fdump-ast print AST
-fdump-stack Print stacktrace
-fno-dump-source Do not emit source code as assembly comment
-o filename Output to the specified file
-g Do nothing at this moment
-Wall Enable all warnings
-Werror Make all warnings into errors
-O Does nothing at this moment
-m64 Output 64-bit code (default)
-w Disable all warnings
-h print this help
One of -a, -c, -E or -S must be specified.
`
i still get this message even if i specify '-a'
What am i doing wrong?
The latest commit, adding backend-specific CLI options, fails tests when building.
[ERROR] parse.c:684: (null): Integer expression expected, but got gv=MCF_CACHE_DEPTH
build.mk:5: recipe for target 'out/elc.c.eir' failed
make: *** [out/elc.c.eir] Error 1
I maintain some fast Befunge implementations: https://github.com/serprex/befunge
Would you be interested in accepting a PR where I've modified bejit to match befunge.cc's lack of bounding area? Would it be preferable if I weren't using indirect gotos?
Sorry for the practical story.
Is it possible to bootstrap 8cc with ELVM and build a compiler structure with 8cc based on ELVM?
While I was trying to investigate some issues with fgets
implementation, I've noticed that the source of the issue is EOF definition itself.
int c = getchar();
if (c < 0) {
printf("%x\n", c);
printf("%x\n", EOF);
}
After running the code snippet above, I have got the following result:
-1
ffffff
As you can see, EOF is 24-bit instead of 32-bit. Therefore, if (c == EOF)
is always false. This can be seen in the generated EIR code as well:
16777215 is simply 0xffffff. This causes some bugs. Even though interpreting the EIR output with eli
works fine for some cases, it still fails if you try to convert EIR to Whitespace for instance.
Since I haven't been able to pinpoint issue yet, I have made temporary fix by changing the condition from c == EOF
to c < 0
. I will make a pull request soon.
By the way, printf
might have issues with hexadecimal representation as well since it literally printed back -1
instead of ffffffff
.
Some really awesome people implemented a whole CPU in Game of Life together with a Tetris implementation in a [custom programming language, a custom assembly language and a custom assembler!
See Build a working game of Tetris in Conway's Game of Life on CodeGolf.SE.
Their language seems quite sophisticated, hence an ELVM backend shouldn't be too hard ๐
This is not a bug as ir_error() never returns, but clang doesn't know that. :-/
cc -c -I. -std=gnu99 -m32 -W -Wall -W -Werror -MMD -MP -O -g -Wno-missing-field-initializers -Wno-missing-field-initializers ir/ir.c -o out/ir.o
ir/ir.c:343:12: error: variable 'argc' is used uninitialized whenever 'if' condition is false
[-Werror,-Wsometimes-uninitialized]
else if (op == (Op)DATA) {
^~~~~~~~~~~~~~
ir/ir.c:351:23: note: uninitialized use occurs here
for (int i = 0; i < argc; i++) {
^~~~
ir/ir.c:343:8: note: remove the 'if' if its condition is always true
else if (op == (Op)DATA) {
^~~~~~~~~~~~~~~~~~~~
ir/ir.c:326:11: note: initialize the variable 'argc' to silence this warning
int argc;
^
= 0
Is making a DOS port relevant? There is no way to check it in plain Linux nor to generate the code on DOS directly...
How to do this?
When I'm trying to do anything from C involving STDIO or other C header files, I just get a report that the header file cannot be found, despite being in /usr/include/.
Command run: ~/elvm2/out/8cc -Ilibc -S wwvsim.c -o wwvsim.eir
Output: [ERROR] cpp.c:716: wwvsim.c:25:1: cannot find header file: stdio.h
Note this happens for EVERY header file. How do I fix this?
System: Devuan GNU/Linux 4 (chimaera) x86_64
Kernel: 5.10.0-18-amd64
Extra info:
/usr/include/stdio.h: File exists
In the C file I am trying to convert, stdio is included as #include <stdio.h>
Help is greatly appreciated. Thank you in advance!
you know, just compile to the SUBLEQ ISA, quite interesting
Any plans to add (limited) support for syscalls, etc.?
Starting with version 7, GCC generates a warning for case
statements without a break
, such as line 419ff or ir/ir.c
:
switch (op) {
case LOAD:
case STORE:
if (g_split_basic_block_by_mem) {
p->pc++;
p->prev_boundary = true;
}
Since the default compilation options of the Makefile include -Werror
, this prevents building most of the toolchain. The easiest fix might be to add -Wno-implicit-fallthrough
to COMMONFLAGS
.
I cloned the latest master (25fade6) and built on a stock Ubuntu 16.04 (gcc 5.4.0, etc.):
$ make
Skip building js due to lack of nodejs
Skip building el due to lack of emacs
Skip building cl due to lack of sbcl
Skip building cpp due to lack of g++-6
Skip building i due to lack of ick
cp test/24_cmp2.c out/24_cmp2.c.tmp && mv out/24_cmp2.c.tmp out/24_cmp2.c
git submodule update --init
Submodule '8cc' (https://github.com/shinh/8cc) registered for path '8cc'
Submodule 'Whitespace' (https://github.com/koturn/Whitespace) registered for path 'Whitespace'
Submodule 'tinycc' (http://repo.or.cz/tinycc.git) registered for path 'tinycc'
Cloning into '8cc'...
remote: Counting objects: 4541, done.
remote: Compressing objects: 100% (187/187), done.
remote: Total 4541 (delta 112), reused 0 (delta 0), pack-reused 4354
Receiving objects: 100% (4541/4541), 1.42 MiB | 1.19 MiB/s, done.
Resolving deltas: 100% (3026/3026), done.
Checking connectivity... done.
Submodule path '8cc': checked out '842752b089019bf883e21604a98e712b55fd7727'
Cloning into 'Whitespace'...
remote: Counting objects: 54, done.
remote: Total 54 (delta 0), reused 0 (delta 0), pack-reused 54
Unpacking objects: 100% (54/54), done.
Checking connectivity... done.
Submodule path 'Whitespace': checked out '16be2c0617a6f7846c53802e1a4cb382ccf7dc8a'
Cloning into 'tinycc'...
remote: Counting objects: 8915, done.
remote: Compressing objects: 100% (2610/2610), done.
remote: Total 8915 (delta 6260), reused 8864 (delta 6217)
Receiving objects: 100% (8915/8915), 2.89 MiB | 531.00 KiB/s, done.
Resolving deltas: 100% (6260/6260), done.
Checking connectivity... done.
Submodule path 'tinycc': checked out 'c948732efaf823f36d05608fe716bfcc4a98b70c'
touch out/git_submodule.stamp
make -C 8cc && cp 8cc/8cc out/8cc
make[1]: Entering directory '/home/ondrej/repos/elvm/8cc'
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o main.o main.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o cpp.o cpp.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o debug.o debug.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o dict.o dict.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o gen.o gen.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o lex.o lex.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o vector.o vector.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o parse.o parse.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o buffer.o buffer.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o map.o map.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o error.o error.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o path.o path.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o file.o file.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o set.o set.c
cc -Wall -Wno-strict-aliasing -std=gnu11 -g -I. -O0 -DBUILD_DIR='"/home/ondrej/repos/elvm/8cc"' -c -o encoding.o encoding.c
cc -o 8cc main.o cpp.o debug.o dict.o gen.o lex.o vector.o parse.o buffer.o map.o error.o path.o file.o set.o encoding.o
make[1]: Leaving directory '/home/ondrej/repos/elvm/8cc'
cc -c -I. -std=gnu99 -m32 -W -Wall -W -Werror -MMD -MP -O -g -Wno-missing-field-initializers -Wno-missing-field-initializers ir/ir.c -o out/ir.o
In file included from /usr/include/stdio.h:27:0,
from ./ir/ir.h:4,
from ir/ir.c:1:
/usr/include/features.h:367:25: fatal error: sys/cdefs.h: No such file or directory
compilation terminated.
Makefile:62: recipe for target 'out/ir.o' failed
make: *** [out/ir.o] Error 1
Is this a bug, or am I missing some package in my Ubuntu installation?
The full console output MIGHT be downloadable from this link, but the revision is 709bea7 and probably the most interesting console output lines are:
(diff -u out/elc.c.eir.out out/elc.c.eir.tex.out > out/elc.c.eir.tex.out.diff.tmp && mv out/elc.c.eir.tex.out.diff.tmp out/elc.c.eir.tex.out.diff) || (cat out/elc.c.eir.tex.out.diff.tmp ; false)
--- out/elc.c.eir.out 2021-04-22 08:11:40.740335000 +0300
+++ out/elc.c.eir.tex.out 2021-04-22 11:34:47.693720200 +0300
@@ -1,63 +1,2 @@
=== test/elc.in ===
-var main = function(getchar, putchar) {
-var a = 0;
-var b = 0;
-var c = 0;
-var d = 0;
-var bp = 0;
-var sp = 0;
-var pc = 0;
-var mem = new Int32Array(1 << 24);
-mem[0] = 1;
-var running = true;
-
-var func0 = function() {
- while (0 <= pc && pc < 512 && running) {
- switch (pc) {
- case -1: // dummy
- break;
-
- case 0:
- if (true) pc = 1 - 1;
- break;
-
- case 1:
- a = getchar();
- if (a == 0) pc = 3 - 1;
- break;
-
- case 2:
- putchar(a);
- if (true) pc = 1 - 1;
- break;
-
- case 3:
- running = false; break;
- }
- pc++;
- }
-};
-
-while (running) {
- switch (pc / 512 | 0) {
- case 0:
- func0();
- break;
- }
-}
-};
-if (typeof require != 'undefined') {
- var sys = require('sys');
- var input = null;
- var ip = 0;
- var getchar = function() {
- if (input === null)
- input = require('fs').readFileSync('/dev/stdin');
- return input[ip++] | 0;
- };
- var putchar = function(c) {
- sys.print(String.fromCharCode(c & 255));
- };
- main(getchar, putchar);
-}
diff.mk:4: recipe for target 'out/elc.c.eir.tex.out.diff' failed
make: *** [out/elc.c.eir.tex.out.diff] Error 1
I used
make -j 3
for building. The environment:
tsw1@DESKTOP-H12EA8D:~/m_local/bin_p/ELVM/v2021_04_08/elvm$ uname -a
Linux DESKTOP-H12EA8D 4.4.0-19041-Microsoft #488-Microsoft Mon Sep 01 13:43:00 PST 2020 x86_64 GNU/Linux
tsw1@DESKTOP-H12EA8D:~/m_local/bin_p/ELVM/v2021_04_08/elvm$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 6.3.0-18+deb9u1' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)
As suggested by @shinh in #118 (comment), a Grass backend would be exciting.
I'm currently developing a Grass backend at my repo GrassVM, based on LambdaVM. The VM itself is already working, and I've managed to make rot13.w.
The remaining task is to generate the assembly listing and the memory initialization list in ELVM using C. The current GrassVM code uses plant
included in @susisu's Grassy toolkit to generate rot13.w, which transpiles an OCaml-like language to Grass.
I currently believe that generating the assembly list faces a tradeoff of either using a lot of the stack or requiring a tremendous amount of code size having lots of W
and w
s. To optimize the code size, we would use lots of v
s to refresh the De Bruijn index once in a while, but that would use a lot of the main environment stack. To optimize the stack size, we would squeeze a lot of code in one v
definition clause, but that would increase the De Bruijn index in the sub-environment, probably making the code size increase quadratically with the instruction length. I'll first try if the code size optimized version works. I'll be happy to discuss ideas and collaborate on building this backend.
Iterator overflows at reverse loops
Test code:
#include "libc/_raw_print.h"
int main()
{
for (int i = 0; i <= 5; i++)
{
print_int(i);
putchar(' ');
}
putchar('\n');
for (int i = 5; i >= 0; i--)
{
print_int(i);
putchar(' ');
}
}
compile: out/8cc -Ilibc -S test.c -o test.o
run: out/eli test.o
program output:
0 1 2 3 4 5
5 4 3 2 1 0 16777215 16777214 16777213 (...)
Minecraft functions can run any algorithm, however they are a very verbose and a pain to work with. Is there any interest in a Minecraft command backend?
After running make
for about 60 hours, 108 GB of disk space was taken up, and the tests were not finished. I have some suggestions to make building and testing better:
configure
script to set the languages to build (via the presence of tools on the system and command-line flags like --enable-c
and --disable-tm
), which will generate a Makefile from a template (via automake
).build
and test
).build-cpp
and test-js
).test-full
target that runs expensive tests (e.g. 3-stage bootstrap tests), which are not included in the regular test
target.Frequently when using the online demo, attempting to assemble the ELVM IR just prints:
undefined sym: __builtin_mul
It seems to occur anytime multiplication is needed. For example, the code below throws the error above:
int main(void) { printf("%d", 6 * 3); }
This may not just be the online demo but I suspect that it is.
I would love to see a pure HTML5 implementation.
The compiler always emits ADD A, 1
for the increment operator. This is incorrect if the operand is a pointer to something with size != 1. Although all primitive values in ELVM have size == 1, structures can still have it different.
I see that ELVM supports input, but not the demo site, input can only be passed using DevTools, so maybe it will be neccessary to add input to the demo site.
For following code
#include <stdio.h>
static const int SIZE = 8;
static int* board;
static int count = 0;
int main()
{
board = malloc(SIZE * sizeof(*board));
nQueens(0);
printf("%d", count);
free(board);
return 0;
}
int nQueens(int row)
{
for(int i=0; i<SIZE; i++)
{
for(int j=0;j<row;j++)
{
if(board[j] == i || row - j == abs(i - board[j]))
{
goto OUTER;
}
}
board[row] = i;
if(row >= SIZE - 1)
{
++count;
return 0;
}
nQueens(row + 1);
OUTER:
;
}
return 0;
}
int abs(int input){
return input<0?-input:input;
}
online demo prints 2113, while being compiled with gcc it prints correct 92.
Greetings.....so as far as I can tell, this compiler doesn't encode volatile semantics in the IR....(maybe I am mistaken...if so let me know).
So I guess ultimately the problem is this:
volatile unsigned char x; void foo() { while (x != 12){} }
The c backend would generate something equivalent to this:
unsigned char x; void foo() { while (x != 12){} }
And then the compiler that you feed this into (which could be an optimizing compiler) will say....oops x is never changed, so I am going to just optimize out all but the first check on the loop (https://godbolt.org/z/CXsSfg)
Anyways.....let me what are your plans are in this regard? (A legitimate response can be that is outside scope.....)
9cc is a successor of 8cc, 9cc can be understood extremely easily while creating a compiler that generates reasonably efficient assembly. Will 9cc be modified to generate elvm IR?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.