1- // Generated by purs version 0.15.15
1+ // Parse the NuttX Exception and NuttX Stack Dump. Explain the NuttX Exception.
2+ // Based on https://github.com/purescript-contrib/purescript-string-parsers/blob/main/test/Examples.purs
3+ // Main Module will be started by `spago run`
24import * as Control_Applicative from "https://compile.purescript.org/output/Control.Applicative/index.js" ;
35import * as Control_Apply from "https://compile.purescript.org/output/Control.Apply/index.js" ;
46import * as Control_Bind from "https://compile.purescript.org/output/Control.Bind/index.js" ;
@@ -17,6 +19,23 @@ import * as StringParser_CodePoints from "https://compile.purescript.org/output/
1719import * as StringParser_Parser from "https://compile.purescript.org/output/StringParser.Parser/index.js" ;
1820var discard = /* #__PURE__ */ Control_Bind . discard ( Control_Bind . discardUnit ) ;
1921var discard1 = /* #__PURE__ */ discard ( StringParser_Parser . bindParser ) ;
22+
23+ // To parse the line: `stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000`
24+ // If the line begins with a Timestamp: `[ 6.242000] `
25+ // Skip `[ `
26+ // `void` means ignore the Text Captured
27+ // `$ something something` is shortcut for `( something something )`
28+ // `<*` is the Delimiter between Patterns
29+ // void $
30+ // string "[" -- Match the string `[`
31+ // <* skipSpaces -- Skip the following spaces
32+ // <* regex "[.0-9]+" -- Skip the number
33+ // <* string "]" -- Match the string `]`
34+ // <* skipSpaces -- Skip the following spaces
35+ // Skip `stack_dump: `
36+ // `void` means ignore the Text Captured
37+ // `$ something something` is shortcut for `( something something )`
38+ // `<*` is the Delimiter between Patterns
2039var $$void = /* #__PURE__ */ Data_Functor [ "void" ] ( StringParser_Parser . functorParser ) ;
2140var applyFirst = /* #__PURE__ */ Control_Apply . applyFirst ( StringParser_Parser . applyParser ) ;
2241var bind = /* #__PURE__ */ Control_Bind . bind ( StringParser_Parser . bindParser ) ;
@@ -32,34 +51,44 @@ var logShow = /* #__PURE__ */ Effect_Console.logShow(/* #__PURE__ */ showRecord(
3251 return "pos" ;
3352 }
3453} ) ( Data_Show . showInt ) ) ( Data_Show . showString ) ) ) ;
54+
55+ // Address can point to Code, Data, BSS or Heap
3556var Code = /* #__PURE__ */ ( function ( ) {
3657 function Code ( ) {
3758
3859 } ;
3960 Code . value = new Code ( ) ;
4061 return Code ;
4162} ) ( ) ;
63+
64+ // Address can point to Code, Data, BSS or Heap
4265var Data = /* #__PURE__ */ ( function ( ) {
4366 function Data ( ) {
4467
4568 } ;
4669 Data . value = new Data ( ) ;
4770 return Data ;
4871} ) ( ) ;
72+
73+ // Address can point to Code, Data, BSS or Heap
4974var BSS = /* #__PURE__ */ ( function ( ) {
5075 function BSS ( ) {
5176
5277 } ;
5378 BSS . value = new BSS ( ) ;
5479 return BSS ;
5580} ) ( ) ;
81+
82+ // Address can point to Code, Data, BSS or Heap
5683var Heap = /* #__PURE__ */ ( function ( ) {
5784 function Heap ( ) {
5885
5986 } ;
6087 Heap . value = new Heap ( ) ;
6188 return Heap ;
6289} ) ( ) ;
90+
91+ // How to display an Address Type
6392var showAddressType = {
6493 show : function ( v ) {
6594 if ( v instanceof Code ) {
@@ -77,6 +106,9 @@ var showAddressType = {
77106 throw new Error ( "Failed pattern match at Main (line 73, column 1 - line 77, column 21): " + [ v . constructor . name ] ) ;
78107 }
79108} ;
109+
110+ // NuttX Kernel: 0x5020_0000 to 0x5021_98ac
111+ // NuttX App (qjs): 0x8000_0000 to 0x8006_4a28
80112var logShow1 = /* #__PURE__ */ Effect_Console . logShow ( /* #__PURE__ */ Data_Maybe . showMaybe ( /* #__PURE__ */ showRecord ( /* #__PURE__ */ Data_Show . showRecordFieldsCons ( {
81113 reflectSymbol : function ( ) {
82114 return "origin" ;
@@ -86,6 +118,11 @@ var logShow1 = /* #__PURE__ */ Effect_Console.logShow(/* #__PURE__ */ Data_Maybe
86118 return "type" ;
87119 }
88120} ) ( showAddressType ) ) ( Data_Show . showString ) ) ) ) ;
121+
122+ // Parse a line of NuttX Stack Dump.
123+ // Given this line of NuttX Stack Dump: `stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000`
124+ // Result: { addr: "c02027e0", timestamp: "6.242000", v1: "c0202010", v2: "00000000", v3: "00000001", v4: "00000000", v5: "00000000", v6: "00000000", v7: "8000ad8a", v8: "00000000" }
125+ // The next line declares the Function Type. We can actually erase it, VSCode PureScript Extension will helpfully suggest it for us.
89126var parseStackDump = /* #__PURE__ */ discard1 ( /* #__PURE__ */ $$void ( /* #__PURE__ */ applyFirst ( /* #__PURE__ */ StringParser_CodePoints . string ( "stack_dump:" ) ) ( StringParser_CodePoints . skipSpaces ) ) ) ( function ( ) {
90127 return discard1 ( $$void ( StringParser_CodePoints . string ( "0x" ) ) ) ( function ( ) {
91128 return bind ( applyFirst ( applyFirst ( StringParser_CodePoints . regex ( "[0-9a-f]+" ) ) ( StringParser_CodePoints . string ( ":" ) ) ) ( StringParser_CodePoints . skipSpaces ) ) ( function ( addr ) {
@@ -119,6 +156,15 @@ var parseStackDump = /* #__PURE__ */ discard1(/* #__PURE__ */ $$void(/* #__PURE_
119156 } ) ;
120157 } ) ;
121158} ) ;
159+
160+ // Parse the line of NuttX Stack Dump with Timestamp
161+ // Result: { addr: "c02027e0", v1: "c0202010", v2: "00000000", v3: "00000001", v4: "00000000", v5: "00000000", v6: "00000000", v7: "8000ad8a", v8: "00000000" }
162+ // doRunParser "parseStackDump" parseStackDump
163+ // "[ 6.242000] stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000"
164+ // Parse the NuttX Exception.
165+ // Given this NuttX Exception: `riscv_exception: EXCEPTION: Instruction page fault. MCAUSE: 000000000000000c, EPC: 000000008000ad8a, MTVAL: 000000008000ad8a`
166+ // Result: { epc: "8000ad8a", exception: "Instruction page fault", mcause: 12, mtval: "8000ad8a" }
167+ // The next line declares the Function Type. We can actually erase it, VSCode PureScript Extension will helpfully suggest it for us.
122168var parseException = /* #__PURE__ */ discard1 ( /* #__PURE__ */ $$void ( /* #__PURE__ */ applyFirst ( /* #__PURE__ */ applyFirst ( /* #__PURE__ */ applyFirst ( /* #__PURE__ */ StringParser_CodePoints . string ( "riscv_exception:" ) ) ( StringParser_CodePoints . skipSpaces ) ) ( /* #__PURE__ */ StringParser_CodePoints . string ( "EXCEPTION:" ) ) ) ( StringParser_CodePoints . skipSpaces ) ) ) ( function ( ) {
123169 return bind ( applyFirst ( applyFirst ( StringParser_CodePoints . regex ( "[^.]+" ) ) ( StringParser_CodePoints . string ( "." ) ) ) ( StringParser_CodePoints . skipSpaces ) ) ( function ( exception ) {
124170 return discard1 ( $$void ( applyFirst ( StringParser_CodePoints . string ( "MCAUSE:" ) ) ( StringParser_CodePoints . skipSpaces ) ) ) ( function ( ) {
@@ -141,12 +187,17 @@ var parseException = /* #__PURE__ */ discard1(/* #__PURE__ */ $$void(/* #__PURE_
141187 } ) ;
142188 } ) ;
143189} ) ;
190+
191+ // Return True if the Address matches the Regex Pattern.
192+ // Pattern is assumed to match the Entire Address.
144193var matches = function ( pattern ) {
145194 return function ( addr ) {
146195 var patternWrap = "^" + ( pattern + "$" ) ;
147196 return Data_Maybe . isJust ( Data_String_Regex . match ( Data_String_Regex_Unsafe . unsafeRegex ( patternWrap ) ( Data_String_Regex_Flags . noFlags ) ) ( addr ) ) ;
148197 } ;
149198} ;
199+
200+ // Given an Address, identify the Origin (NuttX Kernel or App) and Type (Code / Data / BSS / Heap)
150201var identifyAddress = function ( addr ) {
151202 if ( matches ( "502....." ) ( addr ) ) {
152203 return new Data_Maybe . Just ( {
@@ -165,6 +216,10 @@ var identifyAddress = function (addr) {
165216 } ;
166217 throw new Error ( "Failed pattern match at Main (line 57, column 1 - line 57, column 74): " + [ addr . constructor . name ] ) ;
167218} ;
219+
220+ // Given this NuttX Exception: `riscv_exception: EXCEPTION: Load page fault. MCAUSE: 000000000000000d, EPC: 000000008000a0e4, MTVAL: 0000000880203b88`
221+ // Explain in friendly words: "We hit a Load Page Fault. Our code at Code Address 8000a0e4 tried to access the Data Address 0000000880203b88, which is Invalid."
222+ // The next line declares the Function Type. We can actually erase it, VSCode PureScript Extension will helpfully suggest it for us.
168223var explainException = function ( v ) {
169224 return function ( v1 ) {
170225 return function ( v2 ) {
@@ -178,6 +233,10 @@ var explainException = function (v) {
178233 } ;
179234 } ;
180235} ;
236+
237+ // Shows the results of calling `runParser`. We typically don't want to use
238+ // this function when writing a parser because it doesn't help us debug
239+ // our code when we write it incorrectly.
181240var doRunParser = function ( dictShow ) {
182241 var show1 = Data_Show . show ( dictShow ) ;
183242 return function ( parserName ) {
@@ -193,7 +252,7 @@ var doRunParser = function (dictShow) {
193252 if ( v instanceof Data_Either . Right ) {
194253 return Effect_Console . log ( "Result: " + show1 ( v . value0 ) ) ( ) ;
195254 } ;
196- throw new Error ( "Failed pattern match at Main (line 261 , column 3 - line 263 , column 52): " + [ v . constructor . name ] ) ;
255+ throw new Error ( "Failed pattern match at Main (line 262 , column 3 - line 264 , column 52): " + [ v . constructor . name ] ) ;
197256 } ) ( ) ;
198257 return Effect_Console . log ( "-----" ) ( ) ;
199258 } ;
@@ -255,6 +314,11 @@ var doRunParser2 = /* #__PURE__ */ doRunParser(/* #__PURE__ */ showRecord(/* #__
255314 return "v8" ;
256315 }
257316} ) ( Data_Show . showString ) ) ( Data_Show . showString ) ) ( Data_Show . showString ) ) ( Data_Show . showString ) ) ( Data_Show . showString ) ) ( Data_Show . showString ) ) ( Data_Show . showString ) ) ( Data_Show . showString ) ) ( Data_Show . showString ) ) ) ;
317+
318+ // Test our code. Parse the NuttX Exception and NuttX Stack Dump. Explain the NuttX Exception.
319+ // `Effect` says that it will do Side Effects (printing to console)
320+ // `Unit` means that no value will be returned
321+ // The next line declares the Function Type. We can actually erase it, VSCode PureScript Extension will helpfully suggest it for us.
258322var printResults = function __do ( ) {
259323 Effect_Console . log ( explainException ( 13 ) ( "8000a0e4" ) ( "0000000880203b88" ) ) ( ) ;
260324 Effect_Console . log ( explainException ( 12 ) ( "epc" ) ( "mtval" ) ) ( ) ;
@@ -265,6 +329,11 @@ var printResults = function __do() {
265329 doRunParser1 ( "parseException" ) ( parseException ) ( "riscv_exception: EXCEPTION: Instruction page fault. MCAUSE: 000000000000000c, EPC: 000000008000ad8a, MTVAL: 000000008000ad8a" ) ( ) ;
266330 return doRunParser2 ( "parseStackDump" ) ( parseStackDump ) ( "stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000" ) ( ) ;
267331} ;
332+
333+ // Main Function that will run our Test Code.
334+ // `Effect` says that it will do Side Effects (printing to console)
335+ // `Unit` means that no value will be returned
336+ // The next line declares the Function Type. We can actually erase it, VSCode PureScript Extension will helpfully suggest it for us.
268337var main = printResults ;
269338export {
270339 main ,
0 commit comments