summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/elf.fspec80
-rw-r--r--spec/flac.fspec4
-rw-r--r--src/compiler/compiler.lm50
-rw-r--r--src/compiler/expr.lm2
-rw-r--r--vim/filespec.vim2
5 files changed, 57 insertions, 81 deletions
diff --git a/spec/elf.fspec b/spec/elf.fspec
index 85c4fe7..2776c65 100644
--- a/spec/elf.fspec
+++ b/spec/elf.fspec
@@ -1,37 +1,47 @@
-enum {
- CLASS_NONE,
- CLASS_32,
- CLASS_64
-};
-
struct elf {
- u8 ei_magic[4] | matches('\x7fELF') str;
- u8 ei_class hex; // word size
- u8 ei_data hex; // endianess
- u8 ei_version;
- u8 ei_osabi;
- u8 ei_abi_version;
- u8 padding[7] nul;
- u16 e_type hex;
- u16 e_machine hex;
- u32 e_version;
- select (ei_class) {
- CLASS_32) struct {
- u32 e_entry hex;
- u32 e_phoff;
- u32 e_shoff;
- } elf32;
- CLASS_64) struct {
- u64 e_entry hex;
- u64 e_phoff;
- u64 e_shoff;
- } elf64;
- } arch;
- u32 e_flags hex;
- u16 e_ehsz;
- u16 e_phentsize;
- u16 e_phnum;
- u16 e_shentsize;
- u16 e_shnum;
- u16 e_shstrndx;
+ struct {
+ u8 ei_magic[4] | matches('\x7fELF') str;
+ enum {
+ CLASS_32 = 1,
+ CLASS_64
+ } u8 ei_class hex; // word size
+ enum {
+ ENDIANESS_LE = 1,
+ ENDIANESS_BE
+ } u8 ei_data hex; // endianess
+ u8 ei_version;
+ u8 ei_osabi;
+ u8 ei_abi_version;
+ u8 padding[7] nul;
+ } header;
+
+ struct body {
+ u16 e_type hex;
+ u16 e_machine hex;
+ u32 e_version;
+ select (header.ei_class) {
+ header.CLASS_32) struct {
+ u32 e_entry hex;
+ u32 e_phoff;
+ u32 e_shoff;
+ } elf32;
+ header.CLASS_64) struct {
+ u64 e_entry hex;
+ u64 e_phoff;
+ u64 e_shoff;
+ } elf64;
+ } arch;
+ u32 e_flags hex;
+ u16 e_ehsz;
+ u16 e_phentsize;
+ u16 e_phnum;
+ u16 e_shentsize;
+ u16 e_shnum;
+ u16 e_shstrndx;
+ };
+
+ select (header.ei_class) {
+ 1) struct body le | endianess('le');
+ 2) struct body be | endianess('be');
+ } body;
};
diff --git a/spec/flac.fspec b/spec/flac.fspec
index 9acd9dc..b4f0dab 100644
--- a/spec/flac.fspec
+++ b/spec/flac.fspec
@@ -61,7 +61,7 @@ struct flac {
u32 user_comment_list_length;
struct utf8_string user_comment[user_comment_list_length];
u1 framing_bit | matches(true);
- } vorbis_comment le;
+ } vorbis_comment | endianess('le');
CUESHEET)
struct {
u8 catalog[128] | encoding('ascii') str;
@@ -169,4 +169,4 @@ struct flac {
} subframe;
u16 crc_16 hex;
} frame[until (false)];
-} be;
+} | endianess('be');
diff --git a/src/compiler/compiler.lm b/src/compiler/compiler.lm
index d5b16bb..c51b509 100644
--- a/src/compiler/compiler.lm
+++ b/src/compiler/compiler.lm
@@ -106,14 +106,10 @@ context fspec
ignore / '//' [^\n]* '\n' | space+ /
literal `: `[ `] `| `;
token VISUAL / 'nul' | 'dec' | 'hex' | 'str' /
- token ENDIANESS / 'le' | 'be' /
end
literal `enum `struct
- def endianess
- [name:ENDIANESS]
-
def visual
[name:VISUAL]
@@ -127,7 +123,7 @@ context fspec
def extra
# if set, this field has trivial length, otherwise need to read subscripts
length:collapser::collapsed
- [subscript:subscript* filter:filter* visual:visual? endianess:endianess?] {
+ [subscript:subscript* filter:filter* visual:visual?] {
f:str = ''
has_slice:bool
for l:subscript in repeat(r1) {
@@ -172,8 +168,8 @@ context fspec
# select ((expr)) { ... } name <extra>;
# struct (optional) { ... } name <extra>;
| [container:container::type name:reference::variable::type extra:extra `;]
- # (enum|struct) name { ... } <(le|be)>;
- | [container:container::type endianess:endianess? `;]
+ # (enum|struct) name { ... } <filters>;
+ | [container:container::type filter:filter* `;]
end
def source
@@ -196,17 +192,15 @@ if (!source) {
}
struct scope
- endianess:str
names:map<str, map<str, any>>
end
global g_scopes:list<scope> = new list<scope>()
void
-push_scope(endianess:str) {
+push_scope() {
s:scope = new scope()
s->names = new map<str, map<str, any>>()
- s->endianess = endianess
g_scopes->push_head(s)
}
@@ -271,28 +265,6 @@ container_name_str(s:str) { if (!s) return '<anon>' return s }
str
signed_str(s:bool) { if (s) return 'signed' return 'unsigned' }
-str
-endianess_str(s:str)
-{
- if (s == 'be')
- return 'big-endian'
- else if (s == 'le')
- return 'little-endian'
-
- print('something went wrong!\n')
- exit(1)
-}
-
-str
-endianess_from_decl(d:fspec::declaration::type)
-{
- endianess:str = g_scopes->top->endianess
- if (d.endianess)
- for e:fspec::declaration::endianess in child(d.endianess) endianess = $e
- if (d.extra && d.extra.endianess)
- for e:fspec::declaration::endianess in child(d.extra.endianess) endianess = $e
- return endianess
-}
void
print_declaration(d:fspec::declaration::type)
@@ -334,9 +306,7 @@ print_declaration(d:fspec::declaration::type)
print(' it needs to be filtered with `', $f.function, '`\n')
for v:fspec::declaration::visual in child(d.extra.visual)
- print(' and it should be visualized as `', $v.name, '`\n')
-
- print(' the field is in ', endianess_str(endianess_from_decl(d)), ' byte order\n')
+ print('and it should be visualized as `', $v.name, '`\n')
}
}
@@ -357,7 +327,7 @@ walk(d:fspec::declaration::type)
insert('variable', $i.decl.name, i)
}
} else if ($s.data.type == 'struct') {
- push_scope(endianess_from_decl(d))
+ push_scope()
for i:fspec::container::strukt::item in repeat(s.data.items) {
if (i.data.container)
walk(i.data)
@@ -366,25 +336,21 @@ walk(d:fspec::declaration::type)
}
pop_scope()
} else if ($s.data.type == 'select') {
- push_scope(endianess_from_decl(d))
- print('━━━━ start of (', $s.data.select, ') ━━━━\n')
+ push_scope()
for i:fspec::container::select::item in repeat(s.data.items) {
if (i.expr)
- print('━━━━ (', $i.expr, ')\n')
else
- print('━━━━ DEFAULT\n')
if (i.data.container)
walk(i.data)
else
print_declaration(i.data)
}
- print('━━━━ end of (', $s.data.select, ') ━━━━\n')
pop_scope()
}
}
-push_scope('le')
+push_scope()
for d:fspec::declaration::type in repeat(source.items)
walk(d)
pop_scope()
diff --git a/src/compiler/expr.lm b/src/compiler/expr.lm
index 1ecdc44..c5548cc 100644
--- a/src/compiler/expr.lm
+++ b/src/compiler/expr.lm
@@ -75,7 +75,7 @@ context reference
lex
# reserved
literal `struct `enum `select
- literal `nul `dec `hex `str `be `le
+ literal `nul `dec `hex `str
literal `until `sizeof
token PRIMITIVE / [us][1-9][0-9]* /
literal `( `) `,
diff --git a/vim/filespec.vim b/vim/filespec.vim
index ffa88ff..15664d7 100644
--- a/vim/filespec.vim
+++ b/vim/filespec.vim
@@ -11,7 +11,7 @@ syn region fsComment start="//" skip="\\$" end="$" keepend contains=@fs
syn keyword fsKeyword select until
syn keyword fsStructure enum struct
-syn keyword fsConstant nul dec hex str be le true false
+syn keyword fsConstant nul dec hex str true false
syn match fsPrimitive "[su][1-9][0-9]*"
syn case ignore