Skip to content

Commit c9db9ae

Browse files
authored
Merge pull request #24 from robalb/develop
NASM initial integration
2 parents 992523b + e46ad82 commit c9db9ae

File tree

8 files changed

+352
-156
lines changed

8 files changed

+352
-156
lines changed

compile_musl_binutils.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,13 @@ CC=musl-gcc CFLAGS="-O3 -static --static -static-libgcc -static-libstdc++" CXXFL
6464
# build as and ld
6565
#---------------------
6666
make all
67+
strip --strip-unneeded gas/as-new
68+
strip --strip-unneeded gas/ld-new
6769

6870
#---------------------
6971
# copy as and ld in
7072
# the web assets folder
7173
#---------------------
72-
cp gas/as-new ../webapp/src/assets/gnu-as.elf
73-
cp ld/ld-new ../webapp/src/assets/gnu-ld.elf
74+
cp gas/as-new ../webapp/src/assets/assemblers/gnu-as.elf
75+
cp ld/ld-new ../webapp/src/assets/assemblers/gnu-ld.elf
7476

compile_musl_nasm.sh

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/bin/bash
2+
3+
cd musl_nasm
4+
5+
#---------------------
6+
# check dependencies
7+
#---------------------
8+
requirements=(
9+
"wget"
10+
"musl-gcc"
11+
"gcc"
12+
"make"
13+
)
14+
15+
for cmd in "${requirements[@]}"; do
16+
command -v "$cmd" >/dev/null 2>&1 || { echo >&2 "Required program $cmd is not installed. Aborting."; exit 1; }
17+
done
18+
19+
#---------------------
20+
# clone nasm v3.00
21+
#---------------------
22+
if [ ! -d nasm ] ; then
23+
wget https://www.nasm.us/pub/nasm/releasebuilds/3.00/nasm-3.00.tar.gz
24+
tar -xf nasm-3.00.tar.gz
25+
mv nasm-3.00 nasm
26+
fi
27+
28+
29+
# nasm does not support out-of-tree builds,
30+
# so we simply move into the source dir in
31+
# order to perform our build
32+
cd nasm
33+
34+
35+
#---------------------
36+
# Run ./configure for a
37+
# musl-only static build
38+
#---------------------
39+
common_configure_flags=(
40+
"--disable-gdb"
41+
"--disable-werror"
42+
"--disable-largefile"
43+
"--disable-gc"
44+
)
45+
46+
CC=musl-gcc LDFLAGS="-static" ./configure "${common_configure_flags[@]}"
47+
48+
49+
#---------------------
50+
# build nasm, stripped
51+
#---------------------
52+
make
53+
make strip
54+
55+
#---------------------
56+
# copy nasm in the
57+
# web assets folder
58+
#---------------------
59+
cp nasm ../../webapp/src/assets/assemblers/nasm.elf
60+

musl_nasm/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*
2+
!.gitignore
3+
-171 KB
Binary file not shown.
-164 KB
Binary file not shown.
1.72 MB
Binary file not shown.

webapp/src/core/assemblers.ts

Lines changed: 149 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,173 @@
1-
import fasm_1_73_32 from '../assets/assemblers/fasm.1.73.32.elf?url'
2-
import gnu_as_2_43_50 from '../assets/assemblers/gnu-as.2.43.50.elf?url'
3-
import gnu_ld_2_43_50 from '../assets/assemblers/gnu-ld.2.43.50.elf?url'
1+
import fasm_1_73_32 from "../assets/assemblers/fasm.1.73.32.elf?url";
2+
import gnu_as_2_43_50 from "../assets/assemblers/gnu-as.2.43.50.elf?url";
3+
import gnu_ld_2_43_50 from "../assets/assemblers/gnu-ld.2.43.50.elf?url";
4+
import nasm_3_00 from "../assets/assemblers/nasm.3.00.elf?url";
45

56
export interface Binary {
6-
fileurl: string;
7-
commands: string;
7+
fileurl: string;
8+
commands: string;
89
}
910

1011
export interface DiagnosticLine {
11-
line: number,
12-
error: string
12+
line: number;
13+
error: string;
1314
}
1415

15-
export type DiagnosticsParser = (assemblerLogs: string)=> Array<DiagnosticLine>;
16+
export type DiagnosticsParser = (
17+
assemblerLogs: string,
18+
) => Array<DiagnosticLine>;
1619

1720
export interface AssemblerMode {
18-
id: string;
19-
display_name: string;
20-
description: string;
21-
//a function that will parse assembler errors in a structured format
22-
//that the code editor will understand
23-
diagnosticsParser?: DiagnosticsParser;
24-
binaries: {
25-
assembler: Binary;
26-
// Linker is optional. If absent, we assume that
27-
// the assembler will directly generate an executable
28-
linker?: Binary;
29-
}
21+
id: string;
22+
display_name: string;
23+
description: string;
24+
//a function that will parse assembler errors in a structured format
25+
//that the code editor will understand
26+
diagnosticsParser?: DiagnosticsParser;
27+
binaries: {
28+
assembler: Binary;
29+
// Linker is optional. If absent, we assume that
30+
// the assembler will directly generate an executable
31+
linker?: Binary;
32+
};
3033
}
3134

32-
3335
export type Assemblers_key = keyof typeof assemblers;
3436

3537
/**
36-
* All the assemblers that can be selected from the UI,
37-
*
38-
* Every option provides the compile commands and the
39-
* binaries required to assemble a program into an ELF
40-
*
41-
* When adding a new assembler, make sure you follow these conventions:
42-
* - The input for an assembler must be the file /assembly.s
43-
* - the output from the linker must be the file /program
44-
* - If the linker program is not defined we assume that the assembler
45-
* directly generates the ELF /program
46-
*/
38+
* All the assemblers that can be selected from the UI,
39+
*
40+
* Every option provides the compile commands and the
41+
* binaries required to assemble a program into an ELF
42+
*
43+
* When adding a new assembler, make sure you follow these conventions:
44+
* - The input for an assembler must be the file /assembly.s
45+
* - the output from the linker must be the file /program
46+
* - If the linker program is not defined we assume that the assembler
47+
* directly generates the ELF /program
48+
*/
4749
export const assemblers: Record<string, AssemblerMode> = {
48-
'GNU_trunk': {
49-
id: 'GNU_trunk',
50-
display_name: 'GNU as',
51-
description: 'GNU as + GNU ld, version 2.43.50. Compiled as a static MUSL binary',
52-
diagnosticsParser: gnu_diagnostics,
53-
binaries: {
54-
assembler: {
55-
fileurl: gnu_as_2_43_50,
56-
commands: '/assembler /assembly.s -o /program.o'
57-
},
58-
linker: {
59-
fileurl: gnu_ld_2_43_50,
60-
commands: '/linker /program.o -o /program'
61-
},
62-
},
63-
},
64-
'FASM_trunk': {
65-
id: 'FASM_trunk',
66-
display_name: 'Fasm',
67-
description: 'Flat assembler version 1.73.32',
68-
diagnosticsParser: fasm_diagnostics,
69-
binaries: {
70-
assembler: {
71-
fileurl: fasm_1_73_32,
72-
commands: '/assembler /assembly.s /program',
73-
},
74-
},
75-
}
50+
GNU_trunk: {
51+
id: "GNU_trunk",
52+
display_name: "GNU as",
53+
description:
54+
"GNU as + GNU ld, version 2.43.50. Compiled as a static MUSL binary",
55+
diagnosticsParser: gnu_diagnostics,
56+
binaries: {
57+
assembler: {
58+
fileurl: gnu_as_2_43_50,
59+
commands: "/assembler /assembly.s -o /program.o",
60+
},
61+
linker: {
62+
fileurl: gnu_ld_2_43_50,
63+
commands: "/linker /program.o -o /program",
64+
},
65+
},
66+
},
67+
FASM_trunk: {
68+
id: "FASM_trunk",
69+
display_name: "Fasm",
70+
description: "Flat assembler version 1.73.32",
71+
diagnosticsParser: fasm_diagnostics,
72+
binaries: {
73+
assembler: {
74+
fileurl: fasm_1_73_32,
75+
commands: "/assembler /assembly.s /program",
76+
},
77+
},
78+
},
79+
NASM_trunk: {
80+
id: "NASM_trunk",
81+
display_name: "nasm",
82+
description:
83+
"NASM 3.00 + GNU ld v2.43.50. Both compiled as a static MUSL binary",
84+
diagnosticsParser: nasm_diagnostics,
85+
binaries: {
86+
assembler: {
87+
fileurl: nasm_3_00,
88+
commands: "/assembler -felf64 /assembly.s -o /program.o",
89+
},
90+
linker: {
91+
fileurl: gnu_ld_2_43_50,
92+
commands: "/linker /program.o -o /program",
93+
},
94+
},
95+
},
7696
} as const;
7797

78-
7998
/**
80-
* Assembler Diagnostic parser for the GNU Assembler
81-
* Chatgpt-generated from unit tests
82-
*/
83-
export function gnu_diagnostics(str: string): Array<DiagnosticLine>{
84-
const diagnostics = [];
85-
const lines = str.split('\n');
86-
// Regex to capture lines with a format like: "/assembly.s:<line_number>: <error_message>"
87-
const regex = /\/assembly\.s:(\d+): (Error: .+)/;
88-
for (const line of lines) {
89-
const match = line.match(regex);
90-
if (match) {
91-
diagnostics.push({
92-
line: parseInt(match[1], 10),
93-
error: match[2]
94-
});
95-
}
96-
}
97-
return diagnostics;
99+
* Assembler diagnostic parser for the NASM assembler
100+
* Chatgpt-generated from unit tests
101+
*/
102+
export function nasm_diagnostics(str: string): Array<DiagnosticLine> {
103+
const diagnostics: DiagnosticLine[] = [];
104+
// Split logs into lines
105+
const lines = str.split(/\r?\n/);
106+
// Regex to match NASM errors/warnings
107+
const regex = /^.*:(\d+): (error|warning): (.*)$/;
108+
for (const line of lines) {
109+
const match = line.match(regex);
110+
if (match) {
111+
const lineNumber = Number.parseInt(match[1], 10);
112+
const message = match[3].trim();
113+
diagnostics.push({ line: lineNumber, error: message });
114+
}
115+
}
116+
return diagnostics;
98117
}
99118

119+
/**
120+
* Assembler Diagnostic parser for the GNU Assembler
121+
* Chatgpt-generated from unit tests
122+
*/
123+
export function gnu_diagnostics(str: string): Array<DiagnosticLine> {
124+
const diagnostics = [];
125+
const lines = str.split("\n");
126+
// Regex to capture lines with a format like: "/assembly.s:<line_number>: <error_message>"
127+
const regex = /\/assembly\.s:(\d+): (Error: .+)/;
128+
for (const line of lines) {
129+
const match = line.match(regex);
130+
if (match) {
131+
diagnostics.push({
132+
line: Number.parseInt(match[1], 10),
133+
error: match[2],
134+
});
135+
}
136+
}
137+
return diagnostics;
138+
}
100139

101140
/**
102-
* Assembler Diagnostic parser for the Fasm Assembler
103-
* Chatgpt-generated from unit tests
104-
*/
105-
export function fasm_diagnostics(str: string): Array<DiagnosticLine>{
106-
// Regex to match line number and error message in the input string
107-
const lineRegex = /\/assembly\.s \[(\d+)\]:/;
108-
const errorRegex = /error: .+/;
141+
* Assembler Diagnostic parser for the Fasm Assembler
142+
* Chatgpt-generated from unit tests
143+
*/
144+
export function fasm_diagnostics(str: string): Array<DiagnosticLine> {
145+
// Regex to match line number and error message in the input string
146+
const lineRegex = /\/assembly\.s \[(\d+)\]:/;
147+
const errorRegex = /error: .+/;
109148

110-
const diagnostics = [];
111-
const lines = str.split('\n');
112-
let lineNum = null;
113-
let errorMsg = null;
114-
// Loop through each line to find line number and error message
115-
for (const line of lines) {
116-
const lineMatch = line.match(lineRegex);
117-
const errorMatch = line.match(errorRegex);
118-
// Capture line number if found
119-
if (lineMatch) {
120-
lineNum = parseInt(lineMatch[1]);
121-
}
122-
// Capture error message if found
123-
if (errorMatch) {
124-
errorMsg = errorMatch[0];
125-
// Add to diagnostics array if both line number and error message are found
126-
if (lineNum !== null && errorMsg !== null) {
127-
diagnostics.push({ line: lineNum, error: errorMsg});
128-
lineNum = null;
129-
errorMsg = null;
130-
}
131-
}
132-
}
133-
return diagnostics;
149+
const diagnostics = [];
150+
const lines = str.split("\n");
151+
let lineNum = null;
152+
let errorMsg = null;
153+
// Loop through each line to find line number and error message
154+
for (const line of lines) {
155+
const lineMatch = line.match(lineRegex);
156+
const errorMatch = line.match(errorRegex);
157+
// Capture line number if found
158+
if (lineMatch) {
159+
lineNum = Number.parseInt(lineMatch[1]);
160+
}
161+
// Capture error message if found
162+
if (errorMatch) {
163+
errorMsg = errorMatch[0];
164+
// Add to diagnostics array if both line number and error message are found
165+
if (lineNum !== null && errorMsg !== null) {
166+
diagnostics.push({ line: lineNum, error: errorMsg });
167+
lineNum = null;
168+
errorMsg = null;
169+
}
170+
}
171+
}
172+
return diagnostics;
134173
}

0 commit comments

Comments
 (0)