readme enhancements
This commit is contained in:
parent
17c7bd9bf1
commit
4b6a1331a8
109
README.md
109
README.md
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue