📄 variables.c
字号:
////////////////////////////////////////////////////////////////
//
// S C R I P T H E R M
// A SCRIPTABLE THERMOMETER
//
// entry of the National Semiconductor COP8FLASH Design Contest
// submitted by Alberto Ricci Bitti (C) 2001
// a.riccibitti@ra.nettuno.it
//
//--------------------------------------------------------------
// FOR A BETTER VIEW SET TAB SIZE=4, INDENT SIZE=4
//--------------------------------------------------------------
// FILE : variables.c
// PURPOSE: handles 16 bit integer variables.
// a variable can store a value or the address of
// a function. Function name variables are created
// parsing the program just before it starts.
// Variables are stacked and searched starting from
// the newest.
// Function calls push a special named variable, retval,
// that acts as frame marker and hold the return value
// for the function. The parameters are pushed immediately
// after retval, in calling order. Local variables follow.
//
////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include "errors.h"
#include "memory.h"
#include "language.h"
#include "tokenizer.h"
#include "script.h"
#include "variables.h"
#define MAX_NAMES 62
//names and values are not grouped in a struct
//in order to optimize memory occupation
//VALUES is public as it is accessed for system variables
static ram_pointer_t names [MAX_NAMES];
volatile int values[MAX_NAMES];
//variables stack top
static unsigned char first_free = 0;
//variables below 'first_variable' are function addresses and cannot be assigned
static unsigned char first_variable = 0;
//for a given name pointer, yelds the index in the table
static unsigned char index( ram_pointer_t name)
{ signed char i = first_free - 1;
while(i>=0)
{
if ( names[i] == NULL_NAME)
syntax_error(SYNTAX_ERROR);
else if ( same_token( name, names[i] ) )
return i;
else
i--;
};
syntax_error(EXPECTED_NAME);
return i; //dummy, just to avoid compiler warnig.
}
//inserts a new variable in the table
//names can be duplicated: newer ones hide older ones
void push_variable(ram_pointer_t name, int value)
{
if (first_free == MAX_NAMES) syntax_error(TOO_MANY_NAMES );
names[ first_free ] = name;
values[ first_free++ ] = value;
}
//when calling a function, all the parameter's values are loaded
//as anonymus variables ( "?" )
//when the function body is executed, anonimous variables are named using
//parameter names from the function's head.
void name_parameter(ram_pointer_t name)
{
unsigned char i;
for (i=first_variable; i<first_free; i++)
{
if (peek_flash(names[i]) == '?')
{
names[i] = name;
break;
};
};
}
//the function's return value is the first variable pushed
//its name acts as a marker for restoring the variables status at function end
int pop_frame(void)
{
first_free = index( RETURN_VALUE );
return values[ first_free ];
}
// set/get functions used to store and retrieves values from variables
//given (a pointer to) the name in the program
void set_variable(ram_pointer_t name, int value)
{ unsigned char i;
if (name == NULL_NAME) return;
i = index(name);
if ( i < first_variable && i >= 6 ) syntax_error(EXPECTED_NAME);
values[ i ] = value;
}
int get_variable(ram_pointer_t name)
{
return values[ index(name) ];
}
void clear_variables(void)
{ unsigned char i;
for (i = 0; i < MAX_NAMES; i++)
{
names [ i ] = NULL_NAME;
values[ i ] = 0;
};
first_free = 0;
//system variables are always defined, push them in
push_variable( THERM, 0 );
push_variable( HYS, 0 );
push_variable( THRE, 0 );
push_variable( OUT, 0 );
push_variable( IN, 0 );
push_variable( TIME, 0 );
}
// parses the program and records all function addresses
void register_functions(void)
{
prog = PROGRAM_START;
while (get_token() != END_FILE)
{
if ( token == FUNCTION )
{
if (get_token() != FUNCTION_NAME) syntax_error(SYNTAX_ERROR); //not a valid name
push_variable(token_address, prog);
};
};
first_variable = first_free;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -