Cornell University ECE4760
Interpreters
PIC32MX250F128B
Introduction
Sometimes it is useful to program directly on the PIC32. This can take the form of an interpreter.
Adam Dunkels' uBasic ported to PIC32.
It is useful to be able to write small programs in a scripting language. This example is an interpreter based on a C program written by Adam Dunkels, originally to implement, in his words: A really tiny and stupid BASIC interpreter, written in a few hours for the fun of it. (see http://www.sics.se/~adam/ubasic/).
I hacked it to be more of a tiny and stupid, block-oriented,
bracket-delimited, language and ported it to the PIC32 in MPLABX/GCC. Although the port runs in the Protothreads header, I cannot currently get the interpreter to yield in any useful fashion because it uses reentrant code which breaks the threader. To make this language actually useful, you would need to modify it to have better variable names, arrays, and a scheme for handling PIC32 I/O in a better fashion than just pushing bytes into memory. I
made a very simple interactive download utility so that source code (see example
below) can be written on a PC editor, then sent to the microcontroller by pasting into the terminal window, and terminated with the @
sign. The following two examples demonstrate that the recursive nesting of statements works correctly, that you can input/output variables values to/from C, and that it is easy to add PIC32 i/o controls like outputA below, which outputs bits to port A.
print 'uBasic demo';
print 'cmd line input=', a ;
for i= 0 to 5 {
print 'i=', i ;
k = 0 ;
if i=2 {print 'if i=2'; } ;
while k<3 {for j=1 to 2 {print 'i*j+k=', i*j+k ;}; k=k+1; delay 10;};
};
print 'done' ;
end;
@ # Enter 1=on 0=off -1=toggle on b cmd ;
print 'cmd line input=', a ;
i = 0;
while i<50 {
outputA 1, a ;
delay 100 ;
i = i+1 ;
};
end;
@
The C program
The interpreter is a modified version of the programs on Adam Dunkel's site, and are properly acknowledged in the code. The demo C code puts the interpreter into a thread and controls execution by a command line serial interface. The command line interface has three commands: l lists the current uBasic program, b runs it, d puts the interface into a wait-state until you cut/paste the new program into the command window.
(Code, pt_cornell_1_3_1.h, ZIP of project, uBasic_examples)
uBasic Program structure
The following table shows the syntax of the existing statements. You can easily add your own statements.
+,
-, *, /, %, &, |
), variables and parentheses. The mod operator
is %
.expr1>expr2
or expr1<expr2
or expr1=expr2
. a-z
. The more formal BNF notation for the language is:
<variable> ::= <letter>
<number>
::= 0 to 32768
<variable_value> ::= contents of <variable>
<relation> ::= <expression> ("<" | ">" | "=") <expression>
<expression> ::= <term> {( "+" | "-" | "&" | "|"
) <term>}
<term> ::= <factor>
{( "*" | "/" | "%"
) <factor>}
<factor> ::= <number> | <variable_value> | "(" <expression>
")"
<statement_sequence> ::= <statement> { <statement> }
<statement> ::=
<assignment_statement> | <if_statement> |
<while_statement> | <print_statement> | <for_statement> | <peek_statement> |
<poke_statement> | <delay_statement> | <comment statement>
<comment statement>
::= "#" [<any characters
except ";">]
";"
<assignment_statement> ::= <variable> "=" <expression>
";"
<peek_statement>
::= peek <expression> ","
<variable>
";"
<poke_statement>
::= poke <expression> ","
<expression>
";"
<delay_statement>
::= delay <expression>
";"
<expression> ","
<expression>
";"
<if_statement> ::=
if <relation> "{" <statement_sequence> "}"
[ else "{" <statement_sequence> "}" ] ";"
<while_statement> ::=
while <relation>
"{" <statement_sequence> "}"
";"<for_statement>
::=
for <variable> "=" <expression> to <expression>
"{" <statement_sequence> "}"
";"All statements are terminated with a semicolon. Spaces, tabs, newlines are all ignored. All program constructs must case-match the templates below.
statement |
example |
---|---|
for var = expr to expr { statement; statment; ... } ; |
for i=1 to 10 { j=j+1; print j; } ; |
while relation { statement; statment; ... } ; |
while i<10 { i=i+1; print 'i=',i; } ; |
|
if c<255 {print c; delay(500);} |
print expr, 'string', ... ; |
print 'hi there', i+1; |
peek address, var ; |
peek 3+32, x; # peek address, variable; |
poke address, expr ; |
poke 40, i+2; # poke address, value |
outputA bit_num, operation ; | Sets, clears or toggles portA bits. bit_num parameter is the sum of the values of the bits to toggle. example: bit_num=5 means that bits 0 and 2 are changed. operation takes values 0=clear, 1=set, -1=toggle |
delay expr ; |
delay 500; # milliseconds ; |
# this is a comment statement ; |
# comment ; Upper case in the comment breaks the parser. dont know why yet. |
var = expr ; |
a = (i+1)/j; # assignment ; |
To implement a new statement (in this example outputA above):
Copyright Cornell University August 15, 2018