type.ha (1399B)
1 // An automata. 2 export type automata = struct { 3 curindex: size, 4 curtree: size, 5 start: *state, 6 states: []*state, 7 transitions: []*transition, 8 results: []*opaque, 9 deterministic: bool, 10 }; 11 12 // A state. 13 export type state = struct { 14 index: size, 15 result: (void | size), 16 transitions: []*transition, 17 }; 18 19 // A transition. 20 export type transition = struct { 21 from: *state, 22 to: *state, 23 tree: size, 24 epsilon: bool, 25 negate: bool, // [^x] 26 accepts: []runeset, 27 }; 28 29 export type dot = void; 30 31 // A runeset. 32 export type runeset = (dot | rune | (rune, rune)); 33 34 // Initialize an automata. The caller must free associated resources with 35 // [[finish]] when they have done using it. 36 export fn init() (automata | error) = { 37 const start = alloc(state { 38 index = 0z, 39 result = void, 40 ... 41 })?; 42 const states: []*state = []; 43 append(states, start)?; 44 return automata { 45 curindex = 1z, 46 curtree = 0z, 47 start = start, 48 states = states, 49 ... 50 }; 51 }; 52 53 // Free resources associated with an [[automata]]. 54 export fn finish(mata: *automata) void = { 55 for (let state .. mata.states) 56 state_destroy(state); 57 free(mata.states); 58 for (let trans .. mata.transitions) 59 transition_destroy(trans); 60 free(mata.results); 61 free(mata.transitions); 62 }; 63 64 fn state_destroy(state: *state) void = { 65 free(state.transitions); 66 free(state); 67 }; 68 69 fn transition_destroy(trans: *transition) void = { 70 free(trans.accepts); 71 free(trans); 72 };