This example shows how to use the Urlan library to implement a simple calculator language.
This example shows how to use the Urlan library to implement a simple calculator language.
#include <stdio.h>
#include <string.h>
{
{
case UT_WORD:
{
if( ! val )
if( ur_is(val, UT_DOUBLE) )
*res = ur_double(val);
else if( ur_is(val, UT_INT) || ur_is(val, UT_CHAR) )
*res = (double) ur_int(val);
else
{
ur_wordCStr( cell ) );
}
}
break;
case UT_DOUBLE:
*res = ur_double(cell);
break;
case UT_INT:
case UT_CHAR:
*res = (double) ur_int(cell);
break;
case UT_BLOCK:
case UT_PAREN:
{
UBlockIterM bi;
double num = 0.0;
double right;
#define RIGHT_VAL \
if( ++bi.it == bi.end ) \
return ur_error( ut, UR_ERR_SCRIPT, "Expected operator r-value" ); \
if( ! calc_eval( ut, bi.it, &right ) ) \
return UR_THROW;
{
if( ur_is(bi.
it, UT_WORD) )
{
switch( ur_atom(bi.it) )
{
case UR_ATOM_PLUS:
RIGHT_VAL
num += right;
break;
case UR_ATOM_MINUS:
RIGHT_VAL
num -= right;
break;
case UR_ATOM_ASTERISK:
RIGHT_VAL
num *= right;
break;
case UR_ATOM_SLASH:
RIGHT_VAL
num /= right;
break;
default:
if( ! calc_eval( ut, bi.it, &num ) )
}
}
else if( ur_is(bi.it, UT_SETWORD) )
{
if( ! cell )
ur_double(cell) = num;
}
else
{
if( ! calc_eval( ut, bi.it, &num ) )
}
}
*res = num;
}
break;
default:
*res = 0.0;
break;
}
}
{
int len = strlen( cmd );
if( len )
{
if( blkN )
{
ok = calc_eval( ut, &cell, result );
return ok;
}
}
}
{
static double constants[2] = { 3.14159265358979, 2.71828182845904 };
UAtom atoms[2];
int i;
for( i = 0; i < 2; ++i )
{
ur_double(cell) = constants[i];
}
}
int main( int argc, char** argv )
{
char cmd[ 2048 ];
double result;
(void) argc;
(void) argv;
printf( "Urlan Calculator Example %s (%s)\n", UR_VERSION_STR, __DATE__ );
if( ! ut )
{
printf( "ur_makeEnv failed\n" );
return 255;
}
defineWords( ut );
while( 1 )
{
printf( ")> " );
fflush( stdout );
fgets( cmd, sizeof(cmd), stdin );
if( cmd[0] < ' ' )
{
printf( "\n" );
}
else if( cmd[0] == 'q' )
{
break;
}
else
{
if( calc_evalCStr( ut, cmd, &result ) )
{
printf( "= %f\n", result );
}
else
{
printf(
"%s\n", str.
ptr.
c );
}
}
}
return 0;
}
UStatus ur_blkSliceM(UThread *, UBlockIterM *, const UCell *cell)
Set UBlockIterM to block slice.
Definition block.c:224
UCell * ur_blkAppendNew(UBuffer *, int type)
Add cell to end of block.
Definition block.c:109
UCell * ur_ctxAddWord(UBuffer *, UAtom atom)
Similar to ur_ctxAddWordI(), but safely returns the cell pointer.
Definition context.c:437
UBuffer * ur_ctxSort(UBuffer *)
Sort the internal context search table so ur_ctxLookup() is faster.
Definition context.c:510
void ur_bind(UThread *, UBuffer *blk, const UBuffer *ctx, int bindType)
Bind block to context.
Definition context.c:690
#define ur_strFree
A string is a simple array.
Definition urlan.h:629
void ur_strTermNull(UBuffer *)
Terminate with null character so buffer can be used as a C string.
Definition string.c:1049
void ur_strInit(UBuffer *, int enc, int size)
Initialize buffer to type UT_STRING.
Definition string.c:430
void ur_freeEnv(UThread *)
Free environment and the initial thread.
Definition env.c:480
#define ur_setId(c, t)
Set type and initialize the other 24 bits of UCellId to zero.
Definition urlan.h:701
UIndex ur_tokenize(UThread *, const char *it, const char *end, UCell *res)
Convert a UTF-8 data string into a block.
Definition tokenize.c:1197
UStatus ur_error(UThread *, int errorType, const char *fmt,...)
Create error! exception.
Definition env.c:964
const UCell * ur_wordCell(UThread *, const UCell *cell)
Get word value for read-only operations.
Definition env.c:1132
void ur_toText(UThread *, const UCell *cell, UBuffer *str)
Append textual representation of cell to a string.
Definition env.c:1118
UBuffer * ur_threadContext(UThread *)
Get thread global context.
Definition env.c:934
UThread * ur_makeEnv(const UEnvParameters *)
Allocate UEnv and initial UThread.
Definition env.c:332
@ UR_THROW
Returned to indicate an evaluation exception occured.
Definition urlan.h:117
@ UR_OK
Returned to indicate successful evaluation/operation.
Definition urlan.h:118
#define ur_foreach(bi)
Loop over all members of an iterator struct.
Definition urlan.h:760
#define ur_hold(n)
Convenience macro for ur_holdBuffer().
Definition urlan.h:748
#define ur_release(h)
Convenience macro for ur_releaseBuffer().
Definition urlan.h:749
UAtom * ur_internAtoms(UThread *, const char *words, UAtom *atoms)
Add atoms to the shared environment.
Definition env.c:645
#define ur_buffer(n)
Macro to get buffer known to be in thread dataStore.
Definition urlan.h:750
#define ur_type(c)
Return UrlanDataType of cell.
Definition urlan.h:695
UCell * ur_wordCellM(UThread *, const UCell *cell)
Get modifiable word value.
Definition env.c:1178
UEnvParameters * ur_envParam(UEnvParameters *par)
Initialize UEnvParameters structure to default values.
Definition env.c:288
The UBuffer struct holds information about a resource, usually a chunk of memory.
Definition urlan.h:266
char * c
chars
Definition urlan.h:276
union UBuffer::@312146223224040072236377336057316010374162171270 ptr
This typically holds a pointer to a chunk of memory.
The UEnvParameters struct allows the user to override default buffer and structure sizes.
Definition urlan.h:497
The UThread struct stores the data specific to a thread of execution.
Definition urlan.h:309
A cell holds a single value of a simple type or a reference (often to a UBuffer) for a complex type.
Definition urlan.h:248
The Urlan programmer interface.
UStatus
Definition urlan.h:116
@ UR_ERR_SCRIPT
General script evaluation error.
Definition urlan.h:126
@ UR_BIND_THREAD
Bound to buffer in thread dataStore.
Definition urlan.h:88
int32_t UIndex
This is an index into an array.
Definition urlan.h:150
This header provides fixed atoms which are always present.