readme enhancements

This commit is contained in:
Joseph Poirier 2015-06-16 11:53:43 -05:00
parent 17c7bd9bf1
commit 4b6a1331a8

109
README.md
View file

@ -22,36 +22,37 @@ processors and is easy to port to new targets.
You can run standard C programs straight from the command line: You can run standard C programs straight from the command line:
``` ```
$ picoc myprogram.c $ picoc file.c
``` ```
If your program is split into multiple files you can list them all on the command line. If your program is split into multiple files you can list them all on the
command line.
``` ```
$ picoc myprog1.c myprog2.c myprog3.c $ picoc file1.c file2.c file3.c
``` ```
If your program takes arguments you add them after a '-' character. If your program takes arguments you add them after a '-' character.
``` ```
$ picoc myprogram.c - arg1 arg2 $ picoc file.c - arg1 arg2
``` ```
# Running script files # Running script files
Scripts are slightly simpler than standard C programs - all the system headers Scripts are slightly simpler than standard C programs because, A) all the system
are included automatically for you so you don't need to include them yourself. headers are included automatically for you so you don't need to include them
Also, scripts don't have a main() function - they just have statements which in your file/s and B) scripts don't require a main() function; they have
are run directly. statements that are run directly from the top of a file to the bottom.
``` ```
$ picoc -s myprogram.c $ picoc -s file.c
``` ```
Here's an example script: Here's an example script:
``` ```C
printf("Starting my script\n"); printf("Starting my script\n");
int i; int i;
@ -67,7 +68,7 @@ printf("The total is %d\n", total);
Here's the output from this script: Here's the output from this script:
``` ```
$ ./picoc -s myscript.c $ ./picoc -s script.c
Starting my script Starting my script
i = 0 i = 0
i = 1 i = 1
@ -131,14 +132,16 @@ To change the stack size you can set the STACKSIZE environment variable to a
different value. The value is in bytes. different value. The value is in bytes.
# Compiling picoc # Compiling PicoC
picoc can be compiled for a UNIX/Linux/POSIX host by typing "make". picoc can be compiled for a UNIX/Linux/POSIX host by typing "make".
The test suite can be run by typing "make test". The test suite can be run by typing "make test".
On Windows, use the MSVC++ sln file in the msvc/picoc folder.
# Porting picoc
# Porting PicoC
platform.h is where you select your platform type and specify the includes platform.h is where you select your platform type and specify the includes
etc. for your platform. etc. for your platform.
@ -165,7 +168,7 @@ your target platform.
# Copyright # Copyright
picoc is published under the "New BSD License", see the LICENSE file. PicoC is published under the "New BSD License", see the LICENSE file.
@ -193,7 +196,7 @@ We'll start by defining a simple function in library_foobar.c. We need to do two
Each of the library_XXX.c files defines a list of picoc prototypes for each of Each of the library_XXX.c files defines a list of picoc prototypes for each of
the functions it defines. For example: the functions it defines. For example:
``` ```C
struct LibraryFunction PlatformLibrary[] = struct LibraryFunction PlatformLibrary[] =
{ {
ShowComplex, "void ShowComplex(struct complex *)"}, ShowComplex, "void ShowComplex(struct complex *)"},
@ -210,7 +213,7 @@ prototype. The "{ NULL, NULL }" line at the end is required.
## The native C function ## The native C function
The native C function is called with these parameters: The native C function is called with these parameters:
``` ```C
void MyCFunc(struct ParseState *Parser, void MyCFunc(struct ParseState *Parser,
struct Value *ReturnValue, struct Value *ReturnValue,
struct Value **Param, struct Value **Param,
@ -224,7 +227,7 @@ void MyCFunc(struct ParseState *Parser,
Here's an example function definition of "random" (as defined above): Here's an example function definition of "random" (as defined above):
``` ```C
void Crandom(struct ParseState *Parser, void Crandom(struct ParseState *Parser,
struct Value *ReturnValue, struct Value *ReturnValue,
struct Value **Param, struct Value **Param,
@ -241,18 +244,18 @@ parameter and returns an integer value.
We've seen how to pass integers into functions. What about passing other data types? We've seen how to pass integers into functions. What about passing other data types?
| Type | Method | Comment | Type | Method | Comment
|-----------|-----------------------|------- |-----------|------------------------|-------
| int | Param[x]->Val->Integer| | int | Param[x]->Val->Integer |
| char | Param[x]->Val->Integer| Treated as 'int' here | char | Param[x]->Val->Integer | Treated as 'int' here
| double | Param[x]->Val->FP | Only available on some systems | double | Param[x]->Val->FP | Only available on some systems
| float | Param[x]->Val->FP | Same as 'double' | float | Param[x]->Val->FP | Same as 'double'
| enum | Param[x]->Val->Integer| Gives integer value of enum | enum | Param[x]->Val->Integer | Gives integer value of enum
| pointers | See section below | Slightly more complicated | pointers | See section below | Slightly more complicated
| char * | See section below | Slightly more complicated | char * | See section below | Slightly more complicated
| arrays | See section below | Slightly more complicated | arrays | See section below | Slightly more complicated
| struct | See section below | Slightly more complicated | struct | See section below | Slightly more complicated
| union | See section below | Slightly more complicated | union | See section below | Slightly more complicated
## Passing pointers ## Passing pointers
Pointer parameters are slighty more complicated to access since you have to Pointer parameters are slighty more complicated to access since you have to
@ -261,7 +264,7 @@ dereference the pointer to get at the underlying data.
Here's how we dereference a pointer parameter. In this example I'll be reading Here's how we dereference a pointer parameter. In this example I'll be reading
an 'int *' parameter: an 'int *' parameter:
``` ```C
int IntValue = *(int*)Param[0]->Val->NativePointer; int IntValue = *(int*)Param[0]->Val->NativePointer;
``` ```
@ -269,7 +272,7 @@ int IntValue = *(int*)Param[0]->Val->NativePointer;
In this example I'll be reading a 'char *' parameter. It's pretty similar to In this example I'll be reading a 'char *' parameter. It's pretty similar to
the 'int *' example above: the 'int *' example above:
``` ```C
char *CharPtr = (char*)Param[0]->Val->NativePointer; char *CharPtr = (char*)Param[0]->Val->NativePointer;
``` ```
@ -288,7 +291,7 @@ In library_XXX.c you'll find a function called PlatformLibraryInit(). This is
called before the library prototypes are defined. Here's a quick way to define called before the library prototypes are defined. Here's a quick way to define
a complex number structure as if it was defined in an include file: a complex number structure as if it was defined in an include file:
``` ```C
IncludeRegister("win32.h", IncludeRegister("win32.h",
&win32SetupFunc, &win32SetupFunc,
&win32Functions[0], &win32Functions[0],
@ -297,21 +300,21 @@ IncludeRegister("win32.h",
Or you could just parse the structure directly: Or you could just parse the structure directly:
``` ```C
const char *definition = "struct complex {int i; int j;};"; const char *definition = "struct complex {int i; int j;};";
PicocParse("my lib", definition, strlen(definition), true, false, false); PicocParse("my lib", definition, strlen(definition), true, false, false);
``` ```
The same method works for defining macros too: The same method works for defining macros too:
``` ```C
const char *definition = "#define ABS(a) ((a) < (0) ? -(a) : (a))"; const char *definition = "#define ABS(a) ((a) < (0) ? -(a) : (a))";
PicocParse("my lib", definition, strlen(definition), true, false, false); PicocParse("my lib", definition, strlen(definition), true, false, false);
``` ```
Here's a more sophisticated method, using the internal functions of picoc directly: Here's a more sophisticated method, using the internal functions of picoc directly:
``` ```C
void PlatformLibraryInit() void PlatformLibraryInit()
{ {
struct ParseState Parser; struct ParseState Parser;
@ -337,13 +340,13 @@ That's enough to define the structure in the system. Finally we free the tokens.
Now let's say we're going to define a function to display a complex number. Now let's say we're going to define a function to display a complex number.
Our prototype will look like: Our prototype will look like:
``` ```C
{ShowComplex, "void ShowComplex(struct complex *)"}, {ShowComplex, "void ShowComplex(struct complex *)"},
``` ```
And finally we can define the library function: And finally we can define the library function:
``` ```C
struct complex {int i; int j;}; /* make this C declaration match the picoc one */ struct complex {int i; int j;}; /* make this C declaration match the picoc one */
void ShowComplex(struct ParseState *Parser, void ShowComplex(struct ParseState *Parser,
@ -373,7 +376,7 @@ and floating point values are returned in ReturnValue->Val->FP.
Returning a pointer to a static string or some other allocated data is easy. Returning a pointer to a static string or some other allocated data is easy.
Your return code will look something like: Your return code will look something like:
``` ```C
ReturnValue->Val->NativePointer = "hello"; ReturnValue->Val->NativePointer = "hello";
``` ```
@ -382,7 +385,7 @@ You can define your own stdarg-style library functions like printf(). Your
function prototype should use "..." in the parameter list to indicate the potential function prototype should use "..." in the parameter list to indicate the potential
extra parameters just like the standard stdarg system. Here's an example from clibrary.c: extra parameters just like the standard stdarg system. Here's an example from clibrary.c:
``` ```C
{LibPrintf, "void printf(char *, ...)"}, {LibPrintf, "void printf(char *, ...)"},
``` ```
@ -393,13 +396,13 @@ using the Param[] array.
Take a look at clibrary.c for the full definition of LibPrintf() if you need a Take a look at clibrary.c for the full definition of LibPrintf() if you need a
more complete example. more complete example.
## Sharing native values with picoc ## Sharing native values with PicoC
Sometimes you have native variables you'd like to share with picoc. We can Sometimes you have native variables you'd like to share with picoc. We can
define a picoc value which shares memory with a native variable. Then we store define a picoc value which shares memory with a native variable. Then we store
this variable in the picoc symbol table so your programs can find it by name. this variable in the picoc symbol table so your programs can find it by name.
There's an easy way to do this: There's an easy way to do this:
``` ```C
int RobotIsExploding = 0; int RobotIsExploding = 0;
void PlatformLibraryInit() void PlatformLibraryInit()
@ -413,41 +416,41 @@ void PlatformLibraryInit()
``` ```
The variable RobotIsExploding can be written by your native C program and read The variable RobotIsExploding can be written by your native C program and read
by picoc just like any other picoc variable. In this case it's protected from by PicoC just like any other PicoC variable. In this case it's protected from
being written by the last parameter "IsWritable" being set to FALSE. Set it to being written by the last parameter "IsWritable" being set to FALSE. Set it to
TRUE and picoc will be able to write it too. TRUE and PicoC will be able to write it too.
# How PicoC differs from C90 # How PicoC differs from C90
picoc is a tiny C language, not a complete implementation of C90. It doesn't aim PicoC is a tiny C language, not a complete implementation of C90. It doesn't aim
to implement every single feature of C90 but it does aim to be close enough that to implement every single feature of C90 but it does aim to be close enough that
most programs will run without modification. most programs will run without modification.
picoc also has scripting abilities which enhance it beyond what C90 offers. PicoC also has scripting abilities which enhance it beyond what C90 offers.
## C preprocessor ## C preprocessor
There is no true preprocessor in picoc. The most popular preprocessor features There is no true preprocessor in PicoC. The most popular preprocessor features
are implemented in a slightly limited way. are implemented in a slightly limited way.
## define ## `#`define
define macros are implemented but have some limitations. They can only be used define macros are implemented but have some limitations. They can only be used
as part of expressions and operate a bit like functions. Since they're used in as part of expressions and operate a bit like functions. Since they're used in
expressions they must result in a value. expressions they must result in a value.
## if/ifdef/else/endif ## `#`if/`#`ifdef/`#`else/`#`endif
The conditional compilation operators are implemented, but have some limitations. The conditional compilation operators are implemented, but have some limitations.
The operator "defined()" is not implemented. These operators can only be used at The operator "defined()" is not implemented. These operators can only be used at
statement boundaries. statement boundaries.
## include ## `#`include
include is supported however the level of support depends on the specific port include is supported however the level of support depends on the specific port
of picoc on your platform. Linux/UNIX and cygwin support #include fully. of PicoC on your platform. Linux/UNIX and cygwin support #include fully.
## Function declarations ## Function declarations
This style of function declaration is supported: This style of function declaration is supported:
``` ```C
int my_function(char param1, int param2, char *param3) int my_function(char param1, int param2, char *param3)
{ {
... ...
@ -461,10 +464,10 @@ A few macros are pre-defined:
* PICOC_VERSION - gives the picoc version as a string eg. "v2.1 beta r524" * PICOC_VERSION - gives the picoc version as a string eg. "v2.1 beta r524"
##Function pointers ## Function pointers
Pointers to functions are currently not supported. Pointers to functions are currently not supported.
##Storage classes ## Storage classes
Many of the storage classes in C90 really only have meaning in a compiler so Many of the storage classes in C90 really only have meaning in a compiler so
they're not implemented in picoc. This includes: static, extern, volatile, they're not implemented in picoc. This includes: static, extern, volatile,
register and auto. They're recognised but currently ignored. register and auto. They're recognised but currently ignored.