diff --git a/poincare/Makefile b/poincare/Makefile index 0fca71b00..b112931b5 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -1,5 +1,5 @@ SFLAGS += -Ipoincare/include -objs += $(addprefix poincare/src/, addition.o expression.o integer.o fraction.o expression_lexer.o expression_parser.o) +objs += $(addprefix poincare/src/, addition.o expression.o integer.o fraction.o expression_lexer.o expression_parser.o variable.o) objs += $(addprefix poincare/src/layout/, expression_layout.o fraction_layout.o horizontal_layout.o string_layout.o) tests += $(addprefix poincare/test/, integer.cpp) diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index b3deacadb..f035af418 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -6,5 +6,6 @@ #include #include #include +#include #endif diff --git a/poincare/include/poincare/variable.h b/poincare/include/poincare/variable.h new file mode 100644 index 000000000..08a592588 --- /dev/null +++ b/poincare/include/poincare/variable.h @@ -0,0 +1,21 @@ +#ifndef POINCARE_VARIABLE_H +#define POINCARE_VARIABLE_H + +#include + +class Variable : public Expression { + public: + Variable(char * name); + ~Variable(); + static Variable * VariableNamed(char * name); + ExpressionLayout * createLayout(ExpressionLayout * parent) override; + float approximate() override; + void setValue(float value); + private: + static void RegisterVariable(Variable * v); + static void UnregisterVariable(Variable * v); + char * m_name; + float m_value; +}; + +#endif diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index ecce0df03..b0f14a6f8 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -52,6 +52,7 @@ \/ { return(DIVIDE); } \^ { return(POW); } \+ { return(PLUS); } +[A-Za-z]+ { yylval->string = yytext; return(SYMBOL); } %% diff --git a/poincare/src/expression_parser.y b/poincare/src/expression_parser.y index e3dfd3180..3ccc20800 100644 --- a/poincare/src/expression_parser.y +++ b/poincare/src/expression_parser.y @@ -55,6 +55,7 @@ void poincare_expression_yyerror(yyscan_t scanner, Expression ** expressionOutpu /* The INTEGER token uses the "string" part of the union to store its value */ %token INTEGER +%token SYMBOL /* The DIVIDE and POW tokens use no value */ %token DIVIDE @@ -92,6 +93,7 @@ Root: exp: INTEGER { $$ = new Integer($1); } + | SYMBOL { $$ = new Variable($1); } | exp DIVIDE exp { $$ = new Fraction($1,$3); } | exp PLUS exp { $$ = new Addition($1,$3); } /* | exp POW exp { $$ = new Power($1,$3); } */ diff --git a/poincare/src/variable.cpp b/poincare/src/variable.cpp new file mode 100644 index 000000000..6abac4441 --- /dev/null +++ b/poincare/src/variable.cpp @@ -0,0 +1,55 @@ +#include +#include +#include "layout/string_layout.h" + +Variable ** sRegisteredVariables = NULL; +int16_t sRegisteredVariableCount = 0; +#define MAX_REGISTERED_VARIABLES 10 + +Variable::Variable(char * name) : +m_value(0.0f) { + size_t length = strlen(name); + m_name = (char *)malloc(sizeof(char)*length+1); + memcpy(m_name, name, length); + m_name[length] = 0; + RegisterVariable(this); +} + +Variable::~Variable() { + UnregisterVariable(this); + free(m_name); +} + +float Variable::approximate() { + return m_value; +} + +ExpressionLayout * Variable::createLayout(ExpressionLayout * parent) { + size_t length = strlen(m_name); + return new StringLayout(parent, m_name, length); +} + +Variable * Variable::VariableNamed(char * name) { + for (int16_t i=0; im_name, name) == 0) { + return currentVariable; + } + } + return NULL; +} + +void Variable::setValue(float value) { + m_value = value; +} + +void Variable::RegisterVariable(Variable * v) { + if (sRegisteredVariables == NULL) { + sRegisteredVariables = (Variable **)malloc(MAX_REGISTERED_VARIABLES*sizeof(Variable *)); + } + sRegisteredVariables[sRegisteredVariableCount++] = v; +} + +void Variable::UnregisterVariable(Variable * v) { + // TODO! +}