char *keywordasm1 = ";*********************************************** \n" "; Simple parser for command names \n" "; \n" "; Input: \n" "; w next character in a string \n" "; parse_state current state \n" "; Output: \n" "; parse_state contains current state: \n" "; 0 - initial state \n" "; 1...(parse_state_offset-1) - command code \n" "; parse_state_offset...254 - next state \n" "; 255 - error (not matched) \n" "; Temporary: \n" "; parse_char, parse_state \n" "; Usage: \n" "; 1)clrf parse_state \n" "; 2)call parse with a new character \n" "; 3)check parse_state and perform actions \n" "; 4)repeat from 2) \n" "; Note: \n" "; 1) The parser takes one character as a look-ahead. \n" "; When a command name matches, parse_char contains \n" "; the first character AFTER the name. If it should \n" "; be checked also, initialize and call parse once more \n" "; with the same character first, then others as usually.\n" "; 2) Size of state table is approximately 4 instructions\n" "; per each character of the total characters number \n" "; (e.g. total for commands \"read\" and \"set\" is 7, \n" "; i.e state table is about 21 instructions) \n" "; \n" ";*********************************************** \n" "parse \n" " movwf parse_char ;save new character\n"; char *keywordasm2 = " movfw parse_state ;read current state \n" " skpz \n" " goto parse2 \n" " movfw parse_char ;if initial state, skip whitespaces\n" " addlw -\' \' \n" " skpnz \n" " return \n" " addlw \' \' - \'\\t\' \n" " skpnz \n" " return \n" "parse2 \n" " call parse_table \n" " iorlw 0 ;check if w=0 (look ahead for delimiter succesful) \n" " skpz \n" " movwf parse_state ;store new state \n" " return \n" ";*********************************************** \n" "; State Table \n" "; \n" "; Input: \n" "; parse_state -> current state + parse_state_offset \n" "; Output: \n" "; w -> new state + parse_state_offset \n" "; \n" "; Note \n" "; Zero parse_state means initial state \n" ";*********************************************** \n" "parse_table \n" " movlw high(parse_table_start) \n" " movwf PCLATH \n" " movfw parse_state ;read current state \n" " skpnz ;is it inital? \n" " goto parse_state0 \n" " addlw -parse_state_offset-1 ;remove offset \n" ";jump table with automatic block boundary workaround \n" " addlw low(parse_table_start) \n" " skpnc \n" " incf PCLATH, f \n" " movwf PCL ;-> takeoff \n" " \n" "parse_state_delimiter \n" ";called from state table to check for end of name \n" " movwf parse_state \n" " movfw parse_char \n" " skpnz \n" " retlw 0 \n" " addlw -\' \' \n" " skpnz \n" " retlw 0 \n" " addlw \' \' - \'\\t\' \n" " skpnz \n" " retlw 0 \n" " addlw \'\\t\' - \'(\' \n" " skpnz \n" " retlw 0 \n" " retlw 255 \n" " \n" "parse_table_start\n";