Antlr 2 (#2823)
* grammar and libs * gitignore * parsing * allow empty line as root statement * tolerate #if * config def changes * s * ant build * workaround * compiled tool * grammar for unions * parse unions * layout logic * fix union alignment * union in config * jar * comment * jar * jar * no prefix on root struct * stray space * normalize some enums
This commit is contained in:
parent
94d7a413b2
commit
d3d6c1694a
|
@ -66,7 +66,7 @@
|
||||||
! all the sub-structures are going to be nested within the primary structure, that's
|
! all the sub-structures are going to be nested within the primary structure, that's
|
||||||
! needed to get a proper TunerStudio file
|
! needed to get a proper TunerStudio file
|
||||||
|
|
||||||
struct persistent_config_s
|
struct_no_prefix persistent_config_s
|
||||||
|
|
||||||
struct_no_prefix engine_configuration_s
|
struct_no_prefix engine_configuration_s
|
||||||
|
|
||||||
|
@ -302,8 +302,8 @@ custom vvt_mode_e 1 bits, U08, @OFFSET@, [0:3], @@vvt_mode_e_enum@@
|
||||||
! todo: convert slow ADC to software scheduler and make TIM8 available
|
! todo: convert slow ADC to software scheduler and make TIM8 available
|
||||||
! todo: maybe convert fast ADC to software scheduler as well? less sure about that
|
! todo: maybe convert fast ADC to software scheduler as well? less sure about that
|
||||||
|
|
||||||
#define brain_input_pin_e_enum "NONE", "INVALID", "INVALID", "PA1", "PA2", "PA3", "INVALID", "PA5", "PA6", "PA7", "PA8", "PA9", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "PA15", "INVALID", "INVALID", "INVALID", "PB3", "PB4", "PB5", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "PC6", "PC7", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "PE5", "PE6", "INVALID", "INVALID", "PE9", "INVALID", "PE11", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
#define brain_input_pin_e_enum "NONE", "INVALID", "INVALID", "PA1", "PA2", "PA3", "INVALID", "PA5", "PA6", "PA7", "PA8", "PA9", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "PA15", "INVALID", "INVALID", "INVALID", "PB3", "PB4", "PB5", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "PC6", "PC7", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "PE5", "PE6", "INVALID", "INVALID", "PE9", "INVALID", "PE11", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||||
custom brain_input_pin_e 1 bits, U08, @OFFSET@, [0:7], @@brain_input_pin_e_enum@@
|
custom brain_input_pin_e 1 bits, U08, @OFFSET@, [0:7], @@brain_input_pin_e_enum@@
|
||||||
|
|
||||||
!
|
!
|
||||||
! 'brain_pin_e' is the most flexible kind of pin
|
! 'brain_pin_e' is the most flexible kind of pin
|
||||||
|
@ -312,14 +312,14 @@ custom brain_input_pin_e 1 bits, U08, @OFFSET@, [0:7], @@brain_input_pin_e_
|
||||||
! 'switch_input_pin_e' is a slow digital input suitable for clutch or brake pedal switch but not suitable for VSS or Flex sensor input
|
! 'switch_input_pin_e' is a slow digital input suitable for clutch or brake pedal switch but not suitable for VSS or Flex sensor input
|
||||||
!
|
!
|
||||||
|
|
||||||
#define brain_pin_e_enum "NONE", "INVALID", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15", "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7", "PB8", "PB9", "PB10", "PB11", "PB12", "PB13", "PB14", "PB15", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", "PC15", "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9", "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", "PE0", "PE1", "PE2", "PE3", "PE4", "PE5", "PE6","PE7","PE8","PE9","PE10","PE11","PE12","PE13","PE14","PE15", "PF0","PF1","PF2","PF3","PF4","PF5","PF6","PF7","PF8","PF9","PF10","PF11","PF12","PF13","PF14","PF15", "PG0","PG1","PG2","PG3","PG4","PG5","PG6","PG7","PG8","PG9","PG10","PG11","PG12","PG13","PG14","PG15", "PH0","PH1","PH2","PH3","PH4","PH5","PH6","PH7","PH8","PH9","PH10","PH11","PH12","PH13","PH14","PH15", "PI0","PI1","PI2","PI3","PI4","PI5","PI6","PI7","PI8","PI9","PI10","PI11","PI12","PI13","PI14","PI15", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
#define brain_pin_e_enum "NONE", "INVALID", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15", "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7", "PB8", "PB9", "PB10", "PB11", "PB12", "PB13", "PB14", "PB15", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", "PC15", "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9", "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", "PE0", "PE1", "PE2", "PE3", "PE4", "PE5", "PE6", "PE7", "PE8", "PE9", "PE10", "PE11", "PE12", "PE13", "PE14", "PE15", "PF0", "PF1", "PF2", "PF3", "PF4", "PF5", "PF6", "PF7", "PF8", "PF9", "PF10", "PF11", "PF12", "PF13", "PF14", "PF15", "PG0", "PG1", "PG2", "PG3", "PG4", "PG5", "PG6", "PG7", "PG8", "PG9", "PG10", "PG11", "PG12", "PG13", "PG14", "PG15", "PH0", "PH1", "PH2", "PH3", "PH4", "PH5", "PH6", "PH7", "PH8", "PH9", "PH10", "PH11", "PH12", "PH13", "PH14", "PH15", "PI0", "PI1", "PI2", "PI3", "PI4", "PI5", "PI6", "PI7", "PI8", "PI9", "PI10", "PI11", "PI12", "PI13", "PI14", "PI15", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||||
#define switch_input_pin_e_enum "NONE", "INVALID", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15", "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7", "PB8", "PB9", "PB10", "PB11", "PB12", "PB13", "PB14", "PB15", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", "PC15", "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9", "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", "PE0", "PE1", "PE2", "PE3", "PE4", "PE5", "PE6","PE7","PE8","PE9","PE10","PE11","PE12","PE13","PE14","PE15", "PF0","PF1","PF2","PF3","PF4","PF5","PF6","PF7","PF8","PF9","PF10","PF11","PF12","PF13","PF14","PF15", "PG0","PG1","PG2","PG3","PG4","PG5","PG6","PG7","PG8","PG9","PG10","PG11","PG12","PG13","PG14","PG15", "PH0","PH1","PH2","PH3","PH4","PH5","PH6","PH7","PH8","PH9","PH10","PH11","PH12","PH13","PH14","PH15", "PI0","PI1","PI2","PI3","PI4","PI5","PI6","PI7","PI8","PI9","PI10","PI11","PI12","PI13","PI14","PI15", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
#define switch_input_pin_e_enum "NONE", "INVALID", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15", "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7", "PB8", "PB9", "PB10", "PB11", "PB12", "PB13", "PB14", "PB15", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", "PC15", "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9", "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", "PE0", "PE1", "PE2", "PE3", "PE4", "PE5", "PE6", "PE7", "PE8", "PE9", "PE10", "PE11", "PE12", "PE13", "PE14", "PE15", "PF0", "PF1", "PF2", "PF3", "PF4", "PF5", "PF6", "PF7", "PF8", "PF9", "PF10", "PF11", "PF12", "PF13", "PF14", "PF15", "PG0", "PG1", "PG2", "PG3", "PG4", "PG5", "PG6", "PG7", "PG8", "PG9", "PG10", "PG11", "PG12", "PG13", "PG14", "PG15", "PH0", "PH1", "PH2", "PH3", "PH4", "PH5", "PH6", "PH7", "PH8", "PH9", "PH10", "PH11", "PH12", "PH13", "PH14", "PH15", "PI0", "PI1", "PI2", "PI3", "PI4", "PI5", "PI6", "PI7", "PI8", "PI9", "PI10", "PI11", "PI12", "PI13", "PI14", "PI15", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||||
|
|
||||||
custom brain_pin_e 1 bits, U08, @OFFSET@, [0:7], @@brain_pin_e_enum@@
|
custom brain_pin_e 1 bits, U08, @OFFSET@, [0:7], @@brain_pin_e_enum@@
|
||||||
custom switch_input_pin_e 1 bits, U08, @OFFSET@, [0:7], @@switch_input_pin_e_enum@@
|
custom switch_input_pin_e 1 bits, U08, @OFFSET@, [0:7], @@switch_input_pin_e_enum@@
|
||||||
|
|
||||||
#define output_pin_e_enum "NONE", "INVALID", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15", "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7", "PB8", "PB9", "PB10", "PB11", "PB12", "PB13", "PB14", "PB15", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", "PC15", "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9", "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", "PE0", "PE1", "PE2", "PE3", "PE4", "PE5", "PE6","PE7","PE8","PE9","PE10","PE11","PE12","PE13","PE14","PE15", "PF0","PF1","PF2","PF3","PF4","PF5","PF6","PF7","PF8","PF9","PF10","PF11","PF12","PF13","PF14","PF15", "PG0","PG1","PG2","PG3","PG4","PG5","PG6","PG7","PG8","PG9","PG10","PG11","PG12","PG13","PG14","PG15", "PH0","PH1","PH2","PH3","PH4","PH5","PH6","PH7","PH8","PH9","PH10","PH11","PH12","PH13","PH14","PH15", "PI0","PI1","PI2","PI3","PI4","PI5","PI6","PI7","PI8","PI9","PI10","PI11","PI12","PI13","PI14","PI15", "MC33972_1", "MC33972_2", "MC33972_3", "MC33972_4", "MC33972_5", "MC33972_6", "MC33972_7", "MC33972_8", "MC33972_9", "MC33972_10", "MC33972_11", "MC33972_12", "MC33972_13", "MC33972_14", "MC33972_15", "MC33972_16", "MC33972_17", "MC33972_18", "MC33972_19", "MC33972_20", "MC33972_21", "MC33972_22", "TLE8888_1", "TLE8888_2", "TLE8888_3", "TLE8888_4", "TLE8888_5", "TLE8888_6", "TLE8888_7", "TLE8888_8", "TLE8888_9", "TLE8888_10", "TLE8888_11", "TLE8888_12", "TLE8888_13", "TLE8888_14", "TLE8888_15", "TLE8888_16", "TLE8888_17", "TLE8888_18", "TLE8888_19", "TLE8888_20", "TLE8888_21", "TLE8888_22", "TLE8888_23", "TLE8888_24", "TLE8888_25", "TLE8888_26", "TLE8888_27", "TLE8888_28", "INVALID", "INVALID", "INVALID", "TLE6240_1", "TLE6240_2", "TLE6240_3", "TLE6240_4", "TLE6240_5", "TLE6240_6", "TLE6240_7", "TLE6240_8", "TLE6240_9", "TLE6240_10", "TLE6240_11", "TLE6240_12", "TLE6240_13", "TLE6240_14", "TLE6240_15", "TLE6240_16", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
#define output_pin_e_enum "NONE", "INVALID", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15", "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7", "PB8", "PB9", "PB10", "PB11", "PB12", "PB13", "PB14", "PB15", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", "PC15", "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9", "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", "PE0", "PE1", "PE2", "PE3", "PE4", "PE5", "PE6", "PE7", "PE8", "PE9", "PE10", "PE11", "PE12", "PE13", "PE14", "PE15", "PF0", "PF1", "PF2", "PF3", "PF4", "PF5", "PF6", "PF7", "PF8", "PF9", "PF10", "PF11", "PF12", "PF13", "PF14", "PF15", "PG0", "PG1", "PG2", "PG3", "PG4", "PG5", "PG6", "PG7", "PG8", "PG9", "PG10", "PG11", "PG12", "PG13", "PG14", "PG15", "PH0", "PH1", "PH2", "PH3", "PH4", "PH5", "PH6", "PH7", "PH8", "PH9", "PH10", "PH11", "PH12", "PH13", "PH14", "PH15", "PI0", "PI1", "PI2", "PI3", "PI4", "PI5", "PI6", "PI7", "PI8", "PI9", "PI10", "PI11", "PI12", "PI13", "PI14", "PI15", "MC33972_1", "MC33972_2", "MC33972_3", "MC33972_4", "MC33972_5", "MC33972_6", "MC33972_7", "MC33972_8", "MC33972_9", "MC33972_10", "MC33972_11", "MC33972_12", "MC33972_13", "MC33972_14", "MC33972_15", "MC33972_16", "MC33972_17", "MC33972_18", "MC33972_19", "MC33972_20", "MC33972_21", "MC33972_22", "TLE8888_1", "TLE8888_2", "TLE8888_3", "TLE8888_4", "TLE8888_5", "TLE8888_6", "TLE8888_7", "TLE8888_8", "TLE8888_9", "TLE8888_10", "TLE8888_11", "TLE8888_12", "TLE8888_13", "TLE8888_14", "TLE8888_15", "TLE8888_16", "TLE8888_17", "TLE8888_18", "TLE8888_19", "TLE8888_20", "TLE8888_21", "TLE8888_22", "TLE8888_23", "TLE8888_24", "TLE8888_25", "TLE8888_26", "TLE8888_27", "TLE8888_28", "INVALID", "INVALID", "INVALID", "TLE6240_1", "TLE6240_2", "TLE6240_3", "TLE6240_4", "TLE6240_5", "TLE6240_6", "TLE6240_7", "TLE6240_8", "TLE6240_9", "TLE6240_10", "TLE6240_11", "TLE6240_12", "TLE6240_13", "TLE6240_14", "TLE6240_15", "TLE6240_16", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||||
custom output_pin_e 1 bits, U08, @OFFSET@, [0:7], @@output_pin_e_enum@@
|
custom output_pin_e 1 bits, U08, @OFFSET@, [0:7], @@output_pin_e_enum@@
|
||||||
|
|
||||||
#define pin_output_mode_e_enum "default", "default inverted", "open collector", "open collector inverted"
|
#define pin_output_mode_e_enum "default", "default inverted", "open collector", "open collector inverted"
|
||||||
custom pin_output_mode_e 1 bits, U08, @OFFSET@, [0:1], @@pin_output_mode_e_enum@@
|
custom pin_output_mode_e 1 bits, U08, @OFFSET@, [0:1], @@pin_output_mode_e_enum@@
|
||||||
|
@ -675,7 +675,7 @@ adc_channel_e fuelLevelSensor;+This is the processor pin that your fuel level se
|
||||||
|
|
||||||
struct trigger_config_s @brief Trigger wheel(s) configuration
|
struct trigger_config_s @brief Trigger wheel(s) configuration
|
||||||
|
|
||||||
#define trigger_type_e_enum "custom toothed wheel", "Ford Aspire", "Dodge Neon 1995", "Miata NA", "Miata NB", "GM_7X", "Cooper R50", "Mazda SOHC 4", "60/2", "36/1", "Honda 4+24+1", "Mitsubishi", "Honda 4+24", "Honda 1+4+24", "Dodge Neon 2003", "Mazda DOHC 1+4", "1+1", "INVALID", "Single Tooth", "Dodge Ram 1+16", "60/2 VW", "Honda 1+24", "Dodge Stratus", "36_2_2_2", "Nissan Primera", "dev 2JZ 3/34 simulator", "Rover K", "GM LS 24", "Honda CBR 600", "2JZ_1_12", "Honda CBR 600 custom", "3/1 skipped" , "Dodge Neon 2003 crank", "Miata VVT", "trg34", "trg35", "Subaru 7+6", "Jeep 18-2-2-2", "WIP", "Dodge Neon 1995 crank only", "Jeep XJ 4 cyl", "FiatIAQ_P8", "Mazda Z5", "trg43", "Renix 44-2-2", "Renix 66-2-2-2", "Honda K 12+1", "trg47", "36/2", "Subaru SVX", "1+16", "Subaru 7 without 6", "trg52", "TriTach", "GM 60/2/2/2", "Skoda Favorit", "Barra 3+1 Cam", "Kawa KX450F", "trg58", "trg59", "trg60", "INVALID"
|
#define trigger_type_e_enum "custom toothed wheel", "Ford Aspire", "Dodge Neon 1995", "Miata NA", "Miata NB", "GM_7X", "Cooper R50", "Mazda SOHC 4", "60/2", "36/1", "Honda 4+24+1", "Mitsubishi", "Honda 4+24", "Honda 1+4+24", "Dodge Neon 2003", "Mazda DOHC 1+4", "1+1", "INVALID", "Single Tooth", "Dodge Ram 1+16", "60/2 VW", "Honda 1+24", "Dodge Stratus", "36_2_2_2", "Nissan Primera", "dev 2JZ 3/34 simulator", "Rover K", "GM LS 24", "Honda CBR 600", "2JZ_1_12", "Honda CBR 600 custom", "3/1 skipped", "Dodge Neon 2003 crank", "Miata VVT", "trg34", "trg35", "Subaru 7+6", "Jeep 18-2-2-2", "WIP", "Dodge Neon 1995 crank only", "Jeep XJ 4 cyl", "FiatIAQ_P8", "Mazda Z5", "trg43", "Renix 44-2-2", "Renix 66-2-2-2", "Honda K 12+1", "trg47", "36/2", "Subaru SVX", "1+16", "Subaru 7 without 6", "trg52", "TriTach", "GM 60/2/2/2", "Skoda Favorit", "Barra 3+1 Cam", "Kawa KX450F", "trg58", "trg59", "trg60", "INVALID"
|
||||||
|
|
||||||
custom trigger_type_e 4 bits, U32, @OFFSET@, [0:5], @@trigger_type_e_enum@@
|
custom trigger_type_e 4 bits, U32, @OFFSET@, [0:5], @@trigger_type_e_enum@@
|
||||||
trigger_type_e type;+https://github.com/rusefi/rusefi/wiki/All-Supported-Triggers\nset trigger_type X
|
trigger_type_e type;+https://github.com/rusefi/rusefi/wiki/All-Supported-Triggers\nset trigger_type X
|
||||||
|
@ -1620,6 +1620,11 @@ lambda_table_t lambdaTable;
|
||||||
afr_table_t lambdaTable;
|
afr_table_t lambdaTable;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
! union
|
||||||
|
! lambda_table_t lambdaTable
|
||||||
|
! afr_table_t afrTable
|
||||||
|
! end_union
|
||||||
|
|
||||||
float[FUEL_LOAD_COUNT] lambdaLoadBins;;"", 1, 0.0, 0, 500.0, 2
|
float[FUEL_LOAD_COUNT] lambdaLoadBins;;"", 1, 0.0, 0, 500.0, 2
|
||||||
float[FUEL_RPM_COUNT] lambdaRpmBins;;"RPM", 1, 0.0, 0, 18000.0, 2
|
float[FUEL_RPM_COUNT] lambdaRpmBins;;"RPM", 1, 0.0, 0, 18000.0, 2
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -95,10 +95,17 @@ scalarField: identifier FsioVisible? identifier (fieldOptionsList)?;
|
||||||
arrayField: identifier '[' arrayLengthSpec Iterate? ']' identifier SemicolonedString? (fieldOptionsList)?;
|
arrayField: identifier '[' arrayLengthSpec Iterate? ']' identifier SemicolonedString? (fieldOptionsList)?;
|
||||||
bitField: Bit identifier (',' QuotedString ',' QuotedString)? ('(' 'comment' ':' QuotedString ')')? SemicolonedSuffix?;
|
bitField: Bit identifier (',' QuotedString ',' QuotedString)? ('(' 'comment' ':' QuotedString ')')? SemicolonedSuffix?;
|
||||||
|
|
||||||
|
unionField: 'union' ENDL+ fields 'end_union';
|
||||||
|
|
||||||
field
|
field
|
||||||
: scalarField
|
: scalarField
|
||||||
| arrayField
|
| arrayField
|
||||||
| bitField
|
| bitField
|
||||||
|
| unionField
|
||||||
|
;
|
||||||
|
|
||||||
|
fields
|
||||||
|
: (field ENDL+)+
|
||||||
;
|
;
|
||||||
|
|
||||||
// Indicates X bytes of free space
|
// Indicates X bytes of free space
|
||||||
|
|
|
@ -151,6 +151,13 @@ public class ParseState extends RusefiConfigGrammarBaseListener {
|
||||||
scope = new Scope();
|
scope = new Scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enterUnionField(RusefiConfigGrammarParser.UnionFieldContext ctx) {
|
||||||
|
// Unions behave like a struct as far as scope is concerned (but is processed differently later
|
||||||
|
// to overlap all members, instead of placing them in sequence as in a struct)
|
||||||
|
enterStruct(null);
|
||||||
|
}
|
||||||
|
|
||||||
void handleFieldOptionsList(FieldOptions options, RusefiConfigGrammarParser.FieldOptionsListContext ctx) {
|
void handleFieldOptionsList(FieldOptions options, RusefiConfigGrammarParser.FieldOptionsListContext ctx) {
|
||||||
// Null means no options were configured, use defaults
|
// Null means no options were configured, use defaults
|
||||||
if (ctx == null) {
|
if (ctx == null) {
|
||||||
|
@ -412,6 +419,23 @@ public class ParseState extends RusefiConfigGrammarBaseListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exitUnionField(RusefiConfigGrammarParser.UnionFieldContext ctx) {
|
||||||
|
assert(scope != null);
|
||||||
|
assert(scope.structFields != null);
|
||||||
|
|
||||||
|
// unions must have at least 1 member
|
||||||
|
assert(!scope.structFields.isEmpty());
|
||||||
|
|
||||||
|
Union u = new Union(scope.structFields);
|
||||||
|
|
||||||
|
// Restore the containing scope
|
||||||
|
scope = scopes.pop();
|
||||||
|
|
||||||
|
// Lastly, add the union to the scope
|
||||||
|
scope.structFields.add(u);
|
||||||
|
}
|
||||||
|
|
||||||
private Stack<Float> evalStack = new Stack<>();
|
private Stack<Float> evalStack = new Stack<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import com.rusefi.newparse.parsing.*;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public class ArrayIterateScalarLayout extends ArrayLayout {
|
||||||
|
public ArrayIterateScalarLayout(PrototypeField prototype, int length) {
|
||||||
|
super(prototype, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void emitOne(PrintStream ps, StructNamePrefixer prefixer, int offset, int idx) {
|
||||||
|
// Set element's position within the array
|
||||||
|
this.prototypeLayout.setOffset(offset + this.prototypeLayout.getSize() * idx);
|
||||||
|
|
||||||
|
// Put a 1-based index on the end of the name to distinguish in TS
|
||||||
|
prefixer.setSuffix(Integer.toString(idx + 1));
|
||||||
|
this.prototypeLayout.writeTunerstudioLayout(ps, prefixer);
|
||||||
|
prefixer.resetSuffix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer) {
|
||||||
|
// Time to iterate: emit one scalar per array element, with the name modified accordingly
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
emitOne(ps, prefixer, this.offset, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// C layout is the same if iterated or not, use default implementation
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import com.rusefi.newparse.parsing.*;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public class ArrayIterateStructLayout extends ArrayLayout {
|
||||||
|
public ArrayIterateStructLayout(StructField prototype, int length) {
|
||||||
|
super(prototype, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void emitOne(PrintStream ps, StructNamePrefixer prefixer, int offset, int idx) {
|
||||||
|
// Set element's position within the array
|
||||||
|
this.prototypeLayout.setOffset(offset + this.prototypeLayout.getSize() * idx);
|
||||||
|
|
||||||
|
// Put a 1-based index on the end of the name to distinguish in TS
|
||||||
|
prefixer.setSuffix(Integer.toString(idx + 1));
|
||||||
|
this.prototypeLayout.writeTunerstudioLayout(ps, prefixer);
|
||||||
|
prefixer.resetSuffix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer) {
|
||||||
|
// Time to iterate: emit one scalar per array element, with the name modified accordingly
|
||||||
|
|
||||||
|
for (int i = 0; i < this.length; i++) {
|
||||||
|
emitOne(ps, prefixer, this.offset, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// C layout is the same if iterated or not, use default implementation
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import com.rusefi.newparse.parsing.*;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public class ArrayLayout extends Layout {
|
||||||
|
protected final int length;
|
||||||
|
|
||||||
|
protected final Layout prototypeLayout;
|
||||||
|
|
||||||
|
public ArrayLayout(PrototypeField prototype, int length) {
|
||||||
|
this.length = length;
|
||||||
|
|
||||||
|
if (prototype instanceof ScalarField) {
|
||||||
|
prototypeLayout = new ScalarLayout((ScalarField)prototype);
|
||||||
|
} else if (prototype instanceof EnumField) {
|
||||||
|
prototypeLayout = new EnumLayout((EnumField) prototype);
|
||||||
|
} else if (prototype instanceof StringField) {
|
||||||
|
prototypeLayout = new StringLayout((StringField) prototype);
|
||||||
|
} else if (prototype instanceof StructField) {
|
||||||
|
StructField structPrototype = (StructField)prototype;
|
||||||
|
prototypeLayout = new StructLayout(0, prototype.name, structPrototype.struct);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("unexpected field type during array layout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return this.prototypeLayout.getSize() * this.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAlignment() {
|
||||||
|
// Arrays only need to be aligned on the alignment of the element, not the whole array
|
||||||
|
return this.prototypeLayout.getAlignment();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOffset(int offset) {
|
||||||
|
super.setOffset(offset);
|
||||||
|
this.prototypeLayout.setOffset(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOffsetWithinStruct(int offset) {
|
||||||
|
super.setOffsetWithinStruct(offset);
|
||||||
|
this.prototypeLayout.setOffsetWithinStruct(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Array of " + this.prototypeLayout.toString() + " length " + this.length + " " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer) {
|
||||||
|
this.prototypeLayout.writeTunerstudioLayout(ps, prefixer, this.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps) {
|
||||||
|
// Skip zero length arrays, they may be used for padding
|
||||||
|
if (this.length > 0) {
|
||||||
|
this.prototypeLayout.writeCLayout(ps, this.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import com.rusefi.newparse.parsing.BitGroup;
|
||||||
|
import com.rusefi.newparse.parsing.EnumField;
|
||||||
|
import com.rusefi.newparse.parsing.Type;
|
||||||
|
import com.rusefi.newparse.parsing.UnusedField;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class BitGroupLayout extends Layout {
|
||||||
|
private class BitLayout {
|
||||||
|
public final String name;
|
||||||
|
public final String comment;
|
||||||
|
|
||||||
|
public BitLayout(String name, String comment) {
|
||||||
|
this.name = name;
|
||||||
|
this.comment = comment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final List<BitLayout> bits;
|
||||||
|
|
||||||
|
public BitGroupLayout(BitGroup bitGroup) {
|
||||||
|
int size = bitGroup.bitFields.size();
|
||||||
|
if (size > 32) {
|
||||||
|
throw new RuntimeException("tried to create bit group starting with " + bitGroup.bitFields.get(0).name + " but it contained " + size + " which is more than the maximum of 32.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bits = bitGroup.bitFields.stream().map(bf -> new BitLayout(bf.name, bf.comment)).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Bit group " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer) {
|
||||||
|
for (int i = 0; i < bits.size(); i++) {
|
||||||
|
BitLayout bit = bits.get(i);
|
||||||
|
ps.print(prefixer.get(bit.name));
|
||||||
|
ps.print(" = bits, U32, ");
|
||||||
|
ps.print(this.offset);
|
||||||
|
ps.print(", [");
|
||||||
|
ps.print(i + ":" + i);
|
||||||
|
|
||||||
|
// TODO: print actual bit options
|
||||||
|
ps.print("], \"false\", \"true\"");
|
||||||
|
|
||||||
|
ps.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps) {
|
||||||
|
// always emit all 32 bits
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
ps.print("\t/**\n\t");
|
||||||
|
|
||||||
|
if (i < bits.size()) {
|
||||||
|
BitLayout bit = this.bits.get(i);
|
||||||
|
|
||||||
|
if (bit.comment != null) {
|
||||||
|
ps.println(" * " + bit.comment.replaceAll("[+]", "").replaceAll(";", "").replace("\\n", "\n\t * "));
|
||||||
|
ps.print('\t');
|
||||||
|
}
|
||||||
|
|
||||||
|
ps.println("offset " + this.offsetWithinStruct + " bit " + i + " */");
|
||||||
|
ps.println("\tbool " + bit.name + " : 1;");
|
||||||
|
} else {
|
||||||
|
// Force pad out all bit groups to a full 32b/4B
|
||||||
|
ps.println("offset " + this.offsetWithinStruct + " bit " + i + " */");
|
||||||
|
ps.println("\tbool unusedBit_" + this.offsetWithinStruct + "_" + i + " : 1;");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import com.rusefi.newparse.parsing.EnumField;
|
||||||
|
import com.rusefi.newparse.parsing.FieldOptions;
|
||||||
|
import com.rusefi.newparse.parsing.Type;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public class EnumLayout extends Layout {
|
||||||
|
private final String name;
|
||||||
|
private final Type type;
|
||||||
|
private final String enumType;
|
||||||
|
private final String values;
|
||||||
|
private final FieldOptions options;
|
||||||
|
|
||||||
|
public EnumLayout(EnumField field) {
|
||||||
|
this.name = field.name;
|
||||||
|
this.type = field.type;
|
||||||
|
this.enumType = field.enumType;
|
||||||
|
this.values = field.values;
|
||||||
|
this.options = field.options;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return this.type.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer) {
|
||||||
|
ps.print(prefixer.get(this.name));
|
||||||
|
ps.print(" = bits, ");
|
||||||
|
ps.print(this.type.tsType);
|
||||||
|
ps.print(", ");
|
||||||
|
ps.print(this.offset);
|
||||||
|
ps.print(", ");
|
||||||
|
|
||||||
|
// TODO: automatically compute number of bits required?
|
||||||
|
ps.print("[0:7], ");
|
||||||
|
|
||||||
|
// TODO: where should value define resolution happen?
|
||||||
|
ps.print(this.values);
|
||||||
|
|
||||||
|
ps.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps) {
|
||||||
|
this.writeCOffsetHeader(ps, this.options.comment, this.options.units);
|
||||||
|
ps.println("\t" + this.enumType + " " + this.name + ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps, int arrayLength) {
|
||||||
|
this.writeCOffsetHeader(ps, this.options.comment, this.options.units);
|
||||||
|
ps.println("\t" + this.enumType + " " + this.name + "[" + arrayLength + "];");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public abstract class Layout {
|
||||||
|
public int offset = -1;
|
||||||
|
public int offsetWithinStruct = -1;
|
||||||
|
|
||||||
|
public abstract int getSize();
|
||||||
|
public int getAlignment() {
|
||||||
|
// Default to size
|
||||||
|
return this.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffset(int offset) {
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffsetWithinStruct(int offset) {
|
||||||
|
offsetWithinStruct = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "offset = " + offset + " size = " + this.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void writeTunerstudioLayout(PrintStream ps) {
|
||||||
|
writeTunerstudioLayout(ps, new StructNamePrefixer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer) {}
|
||||||
|
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer, int arrayLength) {
|
||||||
|
throw new IllegalStateException("This type can't be in an array!");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeCOffsetHeader(PrintStream ps, String comment, String units) {
|
||||||
|
ps.println("\t/**");
|
||||||
|
|
||||||
|
if (comment != null) {
|
||||||
|
comment = comment.replaceAll(";", "");
|
||||||
|
comment = comment.replaceAll("[+]", "");
|
||||||
|
comment = comment.replaceAll("\\n", "\n\t * ");
|
||||||
|
if (comment.length() == 0) {
|
||||||
|
comment = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comment != null) {
|
||||||
|
comment = comment.replaceAll("\\\\n", "\n\t * ");
|
||||||
|
|
||||||
|
ps.println("\t * " + comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (units != null && units.length() > 2) {
|
||||||
|
ps.println("\t" + units.replace("\"", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
ps.println("\t * offset " + this.offsetWithinStruct);
|
||||||
|
ps.println("\t */");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeCLayout(PrintStream ps) { }
|
||||||
|
|
||||||
|
public void writeCLayout(PrintStream ps, int arrayLength) {
|
||||||
|
throw new IllegalStateException("This type can't be in an array!");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import com.rusefi.newparse.parsing.FieldOptions;
|
||||||
|
import com.rusefi.newparse.parsing.ScalarField;
|
||||||
|
import com.rusefi.newparse.parsing.Type;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public class ScalarLayout extends Layout {
|
||||||
|
private String name;
|
||||||
|
private Type type;
|
||||||
|
private FieldOptions options;
|
||||||
|
|
||||||
|
public ScalarLayout(ScalarField field) {
|
||||||
|
this.name = field.name;
|
||||||
|
this.options = field.options;
|
||||||
|
this.type = field.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return this.type.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Scalar " + type.cType + " " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printBeforeArrayLength(PrintStream ps, StructNamePrefixer prefixer) {
|
||||||
|
ps.print(prefixer.get(this.name));
|
||||||
|
ps.print(" = scalar, ");
|
||||||
|
ps.print(this.type.tsType);
|
||||||
|
ps.print(", ");
|
||||||
|
ps.print(this.offset);
|
||||||
|
ps.print(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printAfterArrayLength(PrintStream ps) {
|
||||||
|
options.printTsFormat(ps);
|
||||||
|
|
||||||
|
ps.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer, int arrayLength) {
|
||||||
|
printBeforeArrayLength(ps, prefixer);
|
||||||
|
|
||||||
|
ps.print("[");
|
||||||
|
ps.print(arrayLength);
|
||||||
|
ps.print("], ");
|
||||||
|
|
||||||
|
printAfterArrayLength(ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer) {
|
||||||
|
printBeforeArrayLength(ps, prefixer);
|
||||||
|
printAfterArrayLength(ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps) {
|
||||||
|
this.writeCOffsetHeader(ps, this.options.comment, this.options.units);
|
||||||
|
ps.println("\t" + this.type.cType.replaceAll("^int32_t$", "int") + " " + this.name + ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps, int arrayLength) {
|
||||||
|
this.writeCOffsetHeader(ps, this.options.comment, this.options.units);
|
||||||
|
ps.println("\t" + this.type.cType.replaceAll("^int32_t$", "int") + " " + this.name + "[" + arrayLength + "];");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import com.rusefi.newparse.parsing.StringField;
|
||||||
|
import com.rusefi.newparse.parsing.UnusedField;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public class StringLayout extends Layout {
|
||||||
|
private final String name;
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
public StringLayout(StringField field) {
|
||||||
|
this.name = field.name;
|
||||||
|
this.size = field.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return this.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAlignment() {
|
||||||
|
// char can be single aligned
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "String " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer) {
|
||||||
|
ps.print(prefixer.get(this.name));
|
||||||
|
ps.print(" = scalar, ASCII, ");
|
||||||
|
ps.print(this.offset);
|
||||||
|
ps.print(", ");
|
||||||
|
ps.print(size);
|
||||||
|
|
||||||
|
ps.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps) {
|
||||||
|
this.writeCOffsetHeader(ps, null, null);
|
||||||
|
ps.println("\tchar " + this.name + "[" + this.size + "];");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps, int arrayLength) {
|
||||||
|
this.writeCOffsetHeader(ps, null, null);
|
||||||
|
ps.println("\tchar " + this.name + "[" + arrayLength + "][" + this.size + "];");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,204 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import com.rusefi.newparse.parsing.*;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class StructLayout extends Layout {
|
||||||
|
/*private*/public List<Layout> children = new ArrayList<>();
|
||||||
|
|
||||||
|
public final String typeName;
|
||||||
|
private final String name;
|
||||||
|
private final String comment;
|
||||||
|
private final Boolean noPrefix;
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
private static int getAlignedOffset(int offset, int alignment) {
|
||||||
|
// Align each element to its own size
|
||||||
|
if ((offset % alignment) != 0) {
|
||||||
|
return offset + alignment - (offset % alignment);
|
||||||
|
} else {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int padOffsetWithUnused(int offset, int align) {
|
||||||
|
int alignedOffset = getAlignedOffset(offset, align);
|
||||||
|
|
||||||
|
int needsUnused = alignedOffset - offset;
|
||||||
|
|
||||||
|
if (needsUnused > 0) {
|
||||||
|
UnusedLayout ul = new UnusedLayout(needsUnused);
|
||||||
|
ul.setOffset(offset);
|
||||||
|
ul.setOffsetWithinStruct(offset - this.offset);
|
||||||
|
children.add(ul);
|
||||||
|
return alignedOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StructLayout(int offset, String name, Struct parsedStruct) {
|
||||||
|
setOffset(offset);
|
||||||
|
|
||||||
|
this.typeName = parsedStruct.name;
|
||||||
|
this.name = name;
|
||||||
|
this.comment = parsedStruct.comment;
|
||||||
|
this.noPrefix = parsedStruct.noPrefix;
|
||||||
|
|
||||||
|
int initialOffest = offset;
|
||||||
|
|
||||||
|
for (Field f : parsedStruct.fields) {
|
||||||
|
if (f instanceof ArrayField) {
|
||||||
|
ArrayField asf = (ArrayField)f;
|
||||||
|
|
||||||
|
// If not a scalar, you must iterate
|
||||||
|
assert(asf.prototype instanceof ScalarField || asf.iterate);
|
||||||
|
|
||||||
|
if (asf.iterate) {
|
||||||
|
if (asf.prototype instanceof StructField) {
|
||||||
|
// Struct: special case of a struct array
|
||||||
|
offset = addItem(offset, new ArrayIterateStructLayout((StructField)asf.prototype, asf.length));
|
||||||
|
} else {
|
||||||
|
// array of scalars (or enums)
|
||||||
|
offset = addItem(offset, new ArrayIterateScalarLayout(asf.prototype, asf.length));
|
||||||
|
}
|
||||||
|
} else /* not iterate */ {
|
||||||
|
// If not a scalar, you must iterate
|
||||||
|
assert(asf.prototype instanceof ScalarField);
|
||||||
|
|
||||||
|
ScalarField prototype = (ScalarField)asf.prototype;
|
||||||
|
offset = addItem(offset, new ArrayLayout(prototype, asf.length));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
offset = addItem(offset, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Structs are always a multiple of 4 bytes long, pad the end appropriately
|
||||||
|
offset = padOffsetWithUnused(offset, 4);
|
||||||
|
|
||||||
|
size = offset - initialOffest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int addItem(int offset, Field f) {
|
||||||
|
if (f instanceof StructField) {
|
||||||
|
// Special case for structs - we have to compute base offset first
|
||||||
|
StructField sf = (StructField) f;
|
||||||
|
|
||||||
|
return addStruct(offset, sf.struct, sf.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout l = null;
|
||||||
|
if (f instanceof ScalarField) {
|
||||||
|
l = new ScalarLayout((ScalarField)f);
|
||||||
|
} else if (f instanceof EnumField) {
|
||||||
|
l = new EnumLayout((EnumField)f);
|
||||||
|
} else if (f instanceof UnusedField) {
|
||||||
|
l = new UnusedLayout((UnusedField) f);
|
||||||
|
} else if (f instanceof BitGroup) {
|
||||||
|
l = new BitGroupLayout((BitGroup) f);
|
||||||
|
} else if (f instanceof StringField) {
|
||||||
|
l = new StringLayout((StringField) f);
|
||||||
|
} else if (f instanceof Union) {
|
||||||
|
l = new UnionLayout((Union)f);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("unexpected field type during layout");
|
||||||
|
}
|
||||||
|
|
||||||
|
return addItem(offset, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int addItem(int offset, Layout l) {
|
||||||
|
// Slide the offset up by the required alignment of this element
|
||||||
|
offset = padOffsetWithUnused(offset, l.getAlignment());
|
||||||
|
|
||||||
|
// place the element
|
||||||
|
l.setOffset(offset);
|
||||||
|
l.setOffsetWithinStruct(offset - this.offset);
|
||||||
|
children.add(l);
|
||||||
|
|
||||||
|
return offset + l.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int addStruct(int offset, Struct struct, String name) {
|
||||||
|
offset = padOffsetWithUnused(offset, 4);
|
||||||
|
|
||||||
|
// Recurse and build this new struct
|
||||||
|
StructLayout sl = new StructLayout(offset, name, struct);
|
||||||
|
|
||||||
|
sl.setOffsetWithinStruct(offset - this.offset);
|
||||||
|
this.children.add(sl);
|
||||||
|
|
||||||
|
// Update offset with the struct size - it's guaranteed to be a multiple of 4 bytes
|
||||||
|
int structSize = sl.getSize();
|
||||||
|
return offset + structSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return this.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAlignment() {
|
||||||
|
// All structs should be aligned on a 4 byte boundary
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Struct " + this.typeName + " " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer) {
|
||||||
|
if (!this.noPrefix) {
|
||||||
|
ps.println("; start struct " + this.typeName);
|
||||||
|
prefixer.push(this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// print all children in sequence
|
||||||
|
this.children.forEach(c -> c.writeTunerstudioLayout(ps, prefixer));
|
||||||
|
|
||||||
|
if (!this.noPrefix) {
|
||||||
|
prefixer.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.noPrefix) {
|
||||||
|
ps.println("; end struct " + this.typeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps) {
|
||||||
|
this.writeCOffsetHeader(ps, null, null);
|
||||||
|
ps.println("\t" + this.typeName + " " + this.name + ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps, int arrayLength) {
|
||||||
|
this.writeCOffsetHeader(ps, null, null);
|
||||||
|
ps.println("\t" + this.typeName + " " + this.name + "[" + arrayLength + "];");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeCLayoutRoot(PrintStream ps) {
|
||||||
|
if (this.comment != null) {
|
||||||
|
ps.println("/**\n * @brief " + this.comment);
|
||||||
|
ps.println("*/");
|
||||||
|
}
|
||||||
|
|
||||||
|
ps.println("// start of " + this.typeName);
|
||||||
|
ps.println("struct " + this.typeName + " {");
|
||||||
|
|
||||||
|
this.children.forEach(c -> c.writeCLayout(ps));
|
||||||
|
|
||||||
|
ps.println("\t/** total size " + getSize() + "*/");
|
||||||
|
ps.println("};");
|
||||||
|
ps.println();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import java.util.Stack;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class StructNamePrefixer {
|
||||||
|
private Stack<String> stack = new Stack<>();
|
||||||
|
|
||||||
|
public void pop() {
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void push(String name) {
|
||||||
|
stack.push(name + "_");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String suffix = new String();
|
||||||
|
|
||||||
|
public void setSuffix(String suffix) {
|
||||||
|
this.suffix = suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetSuffix() {
|
||||||
|
this.suffix = new String();
|
||||||
|
}
|
||||||
|
|
||||||
|
String get(String name) {
|
||||||
|
return stack.stream().collect(Collectors.joining()) + name + suffix;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import com.rusefi.newparse.parsing.ArrayField;
|
||||||
|
import com.rusefi.newparse.parsing.Field;
|
||||||
|
import com.rusefi.newparse.parsing.ScalarField;
|
||||||
|
import com.rusefi.newparse.parsing.Union;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class UnionLayout extends Layout {
|
||||||
|
private List<Layout> children = new ArrayList<>();
|
||||||
|
|
||||||
|
public UnionLayout(Union u) {
|
||||||
|
for (Field f : u.fields) {
|
||||||
|
// For every child, check if it is the largest, and grow if so
|
||||||
|
if (f instanceof ArrayField) {
|
||||||
|
ArrayField af = (ArrayField)f;
|
||||||
|
|
||||||
|
// we probably don't need union of iterate?
|
||||||
|
assert(!af.iterate);
|
||||||
|
|
||||||
|
ScalarField prototype = (ScalarField)af.prototype;
|
||||||
|
this.children.add(new ArrayLayout(prototype, af.length));
|
||||||
|
} else if (f instanceof ScalarField) {
|
||||||
|
this.children.add(new ScalarLayout((ScalarField)f));
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Tried to create union with member type " + f.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOffset(int offset) {
|
||||||
|
super.setOffset(offset);
|
||||||
|
this.children.stream().forEach(c -> c.setOffset(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOffsetWithinStruct(int offset) {
|
||||||
|
super.setOffsetWithinStruct(offset);
|
||||||
|
this.children.stream().forEach(c -> c.setOffsetWithinStruct(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return this.children.stream().map(l -> l.getSize()).max(Integer::compare).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAlignment() {
|
||||||
|
// The alignment of the union is the largest alignment required by one of the members
|
||||||
|
return this.children.stream().map(l -> l.getAlignment()).max(Integer::compare).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer) {
|
||||||
|
// Simply write out all children - no container necessary as fields can overlap in TS
|
||||||
|
this.children.forEach(c -> c.writeTunerstudioLayout(ps, prefixer));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps) {
|
||||||
|
this.writeCOffsetHeader(ps, "union size " + this.getSize() + ", " + this.children.size() + " members", null);
|
||||||
|
|
||||||
|
// emit an anonymous union that contains all our members
|
||||||
|
ps.println("\tunion {");
|
||||||
|
this.children.forEach(c -> c.writeCLayout(ps));
|
||||||
|
ps.println("\t};");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.rusefi.newparse.layout;
|
||||||
|
|
||||||
|
import com.rusefi.newparse.parsing.EnumField;
|
||||||
|
import com.rusefi.newparse.parsing.Type;
|
||||||
|
import com.rusefi.newparse.parsing.UnusedField;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class UnusedLayout extends Layout {
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
public UnusedLayout(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnusedLayout(UnusedField field) {
|
||||||
|
this.size = field.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return this.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAlignment() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Unused " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTunerstudioLayout(PrintStream ps, StructNamePrefixer prefixer) {
|
||||||
|
ps.println("; unused " + this.size + " bytes at offset " + this.offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCLayout(PrintStream ps) {
|
||||||
|
this.writeCOffsetHeader(ps, null, null);
|
||||||
|
ps.println("\tchar unused" + this.offsetWithinStruct + "[" + this.size + "];");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.rusefi.newparse.parsing;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Union implements Field {
|
||||||
|
public final List<Field> fields;
|
||||||
|
|
||||||
|
public Union(List<Field> fields) {
|
||||||
|
this.fields = fields;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue