-
Notifications
You must be signed in to change notification settings - Fork 0
/
test2.si
67 lines (57 loc) · 2.07 KB
/
test2.si
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# require!("Hash_Table.si");
# compile_error!("this is my error text");
M :: macro {
FOO :: 0;
}
[[ program_entry ]]
main :: proc() {
M!();
# HT :: Hash_Table(str, s64);
# table: HT;
# HT.insert(*table, "abc", 123);
}
# @here
# Got a basic form of macro expansion working. Need to extend it for the other
# built in macros (require, static_if), and then start working on user-defined
# macros.
#
# UPDATE:
# This still has some problems...
# The way we've designed the user-defined macros is that they can get replaced with
# whatever kind of node the macro expands to. But how are we going to validate code
# after that? For example:
#
# make_a_decl :: macro() {
# FOO :: 123;
# }
#
# bar := make_a_decl!();
#
# How are we going to avoid an impossible number of scenarios where a node expects its
# child to be something specific? In this case, the variable expects its initialization
# to be an expression, but it will end up being a declaration. Maybe we should have some
# way to bubble down the expected node type to the point where we create the macro call
# node. Then when we expand it, we make sure that the resulting node is of that type.
# So here, by the time we get to parse_macro_call(), we would have informed it that the
# macro is a MACRO_EXPR, or something. Then when it gets expanded, we throw an error
# because it results in a declaration node instead. That might work, but we'll need to
# work through some of the more complicated cased (like block macros) to be sure.
### Interesting ideas:
# CPU :: struct {
# [[ bitfield_struct(u16) ]]
# Register_16 :: struct {
# [[ bitfield(0, 15) ]] _16: u16;
# [[ bitfield(0, 7) ]] lo: u16;
# [[ bitfield(8, 15) ]] hi: u16;
# [[ bitfield(3, 9) ]] flags: u8;
# }
# AR: Register_16;
# [[ field_alias(AR.lo) ]] A: u16;
# [[ field_alias(AR.hi) ]] R: u16;
# }
# Vec3 :: struct(%T: type) {
# array: [3]T;
# [[ field_alias(array[0]) ]] x: T;
# [[ field_alias(array[1]) ]] y: T;
# [[ field_alias(array[2]) ]] z: T;
# }