summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2018-09-27 17:25:47 +0300
committerJari Vetoniemi <mailroxas@gmail.com>2018-09-27 17:25:47 +0300
commit938399ba5870dde9f78e8edf7586986ad4de9736 (patch)
tree3e969b2eb58580bfa5a576b798b41654f54f41f8
parent48ef6aa409c119130b1aa50fa6588db725d6e746 (diff)
compiler: make endianess a filter
endianess is just a bunch of bitflips anyways syntax for this is harmful as sometimes the files describe endianess itself thus filter is more flexible. Also, make it possible to filter non variable declarations as well.
-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