From b5c82f75ab45b5fae6b2692fdb5562e867cff73c Mon Sep 17 00:00:00 2001 From: Luke Dupin Date: Thu, 23 Jan 2020 21:11:53 -0800 Subject: [PATCH] Variables are now exported --- C--.pro | 4 +++ Helpers/token.cpp | 3 ++ Nodes/constant_node.cpp | 28 ++++++++++++++++ Nodes/constant_node.h | 20 ++++++++++++ Nodes/declare_variable.cpp | 12 +++++-- Nodes/declare_variable.h | 2 +- Nodes/expression_node.cpp | 66 ++++++++++++++++++++++++++++++++++++++ Nodes/expression_node.h | 25 +++++++++++++++ Parser/parser.y | 30 ++++++++++------- Parser/scanner.lex | 9 ++++++ Scripts/scanner.py | 1 + 11 files changed, 184 insertions(+), 16 deletions(-) create mode 100644 Nodes/constant_node.cpp create mode 100644 Nodes/constant_node.h create mode 100644 Nodes/expression_node.cpp create mode 100644 Nodes/expression_node.h diff --git a/C--.pro b/C--.pro index 6e04d00..9d0cfc6 100644 --- a/C--.pro +++ b/C--.pro @@ -27,7 +27,9 @@ MOC_DIR = moc SOURCES += \ Helpers/util.cpp \ Helpers/token.cpp \ + Nodes/constant_node.cpp \ Nodes/error.cpp \ + Nodes/expression_node.cpp \ Nodes/node.cpp \ Nodes/program_node.cpp \ Parser/lex.yy.c \ @@ -39,7 +41,9 @@ SOURCES += \ HEADERS += \ Helpers/util.h \ Helpers/token.h \ + Nodes/constant_node.h \ Nodes/error.h \ + Nodes/expression_node.h \ Nodes/node.h \ Nodes/program_node.h \ Parser/lex_token.h \ diff --git a/Helpers/token.cpp b/Helpers/token.cpp index 7bd0de1..f619568 100644 --- a/Helpers/token.cpp +++ b/Helpers/token.cpp @@ -181,6 +181,9 @@ const char* tokenStr( int token ) case F64: return "F64"; + case BOOL: + return "BOOL"; + case STR: return "STR"; diff --git a/Nodes/constant_node.cpp b/Nodes/constant_node.cpp new file mode 100644 index 0000000..eb3e13e --- /dev/null +++ b/Nodes/constant_node.cpp @@ -0,0 +1,28 @@ +#include "constant_node.h" + +#include +#include "parser.tab.h" + +ConstantNode::ConstantNode( int code, int line, QString value, int type_code, int base ) : + Node( code, line, value ), + _typeCode( type_code ), + _base( base ) +{ + if ( type_code < 0 ) + { + if ( value.contains('.')) + _typeCode = F64; + else + _typeCode = I32; + } +} + +int ConstantNode::typeCode() +{ + return _typeCode; +} + +int ConstantNode::base() +{ + return _base; +} diff --git a/Nodes/constant_node.h b/Nodes/constant_node.h new file mode 100644 index 0000000..46acf9d --- /dev/null +++ b/Nodes/constant_node.h @@ -0,0 +1,20 @@ +#ifndef CONSTANTNODE_H +#define CONSTANTNODE_H + +#include "node.h" + +class ConstantNode : public Node +{ + private: + int _typeCode = -1; + int _base = 10; + + public: + ConstantNode( int code, int line, QString value, int type_code = -1, int base = 10 ); + + int typeCode(); + + int base(); +}; + +#endif // CONSTANTNODE_H diff --git a/Nodes/declare_variable.cpp b/Nodes/declare_variable.cpp index a540c5f..2463835 100644 --- a/Nodes/declare_variable.cpp +++ b/Nodes/declare_variable.cpp @@ -1,6 +1,8 @@ #include "declare_variable.h" -DeclareVariable::DeclareVariable( int code, int line, char* name ) : +#include "expression_node.h" + +DeclareVariable::DeclareVariable( int code, int line, QString name ) : Node( code, line, name ) { } @@ -10,9 +12,13 @@ bool DeclareVariable::codeGenPreChild( QTextStream* stream, Context* context ) if ( Children.count() < 1 ) return false; - auto expression = dynamic_cast(Children[0]); + auto expression = dynamic_cast(Children.last()); QString pad; pad.resize( context->Depth * 4, ' '); - (*stream) << << " " << name + (*stream) << expression->getTypeName( context ) << " " + << _label << " = " + << expression->label() << ";\r\n"; + + return true; } diff --git a/Nodes/declare_variable.h b/Nodes/declare_variable.h index df70d7b..4127675 100644 --- a/Nodes/declare_variable.h +++ b/Nodes/declare_variable.h @@ -6,7 +6,7 @@ class DeclareVariable : public Node { public: - DeclareVariable( int code, int line, char* name ); + DeclareVariable( int code, int line, QString name ); bool codeGenPreChild( QTextStream* stream, Context* context ) override; }; diff --git a/Nodes/expression_node.cpp b/Nodes/expression_node.cpp new file mode 100644 index 0000000..122f072 --- /dev/null +++ b/Nodes/expression_node.cpp @@ -0,0 +1,66 @@ +#include "expression_node.h" + +#include "constant_node.h" + +#include +#include "parser.tab.h" + +ExpressionNode::ExpressionNode( int code, int line, QString label ) : + Node( code, line, label ), + _typeName("Unknown") +{ +} + +QString ExpressionNode::getTypeName( Context* context ) +{ + if ( !_calculated && Children.count() > 0 ) + calculateType( context, Children.last() ); + _calculated = true; + + return _typeName; +} + +int ExpressionNode::getTypeCode( Context* context ) +{ + if ( !_calculated ) + calculateType( context, Children.last() ); + _calculated = true; + + return _typeCode; +} + +void ExpressionNode::calculateType( Context* context, Node* node ) +{ + if ( node->tokenType() == IDENT) + { + } + else + { + auto cn = dynamic_cast(node); + _typeCode = cn->typeCode(); + switch ( _typeCode ) + { + case I8: _typeName = "char"; break; + case I16: _typeName = "short"; break; + case I32: _typeName = "int"; break; + case I64: _typeName = "long"; break; + case I128: _typeName = "long long"; break; + + case U8: _typeName = "unsigned char"; break; + case U16: _typeName = "unsigned short"; break; + case U32: _typeName = "unsigned int"; break; + case U64: _typeName = "unsigned long"; break; + case U128: _typeName = "unsigned long long"; break; + + case F32: _typeName = "float"; break; + case F64: _typeName = "double"; break; + + case BOOL: _typeName = "bool"; break; + case STR: _typeName = "QString"; break; + + default: + _typeName = "Error"; + break; + } + } +} diff --git a/Nodes/expression_node.h b/Nodes/expression_node.h new file mode 100644 index 0000000..75a8668 --- /dev/null +++ b/Nodes/expression_node.h @@ -0,0 +1,25 @@ +#ifndef EXPRESSIONNODE_H +#define EXPRESSIONNODE_H + +#include "node.h" + +#include + +class ExpressionNode : public Node +{ + private: + bool _calculated = false; + int _typeCode = -1; + QString _typeName; + + public: + ExpressionNode( int code, int line, QString label ); + + QString getTypeName( Context* context ); + + int getTypeCode( Context* context ); + + void calculateType( Context* context, Node* node ); +}; + +#endif // EXPRESSIONNODE_H diff --git a/Parser/parser.y b/Parser/parser.y index 7e3a172..3b6d2ba 100644 --- a/Parser/parser.y +++ b/Parser/parser.y @@ -8,6 +8,8 @@ #include #include #include + #include + #include #ifdef CPLUSPLUS extern int yylex(); @@ -96,6 +98,7 @@ %token U128 %token F32 %token F64 +%token BOOL %token STR %token VEC %token HASH @@ -437,41 +440,44 @@ expression_list : expression ',' expression_list expression : var ASSIGN expression { //Create my node - $$ = new Node( $2->code, $1->lineNumber(), $2->stringValue ); + $$ = new ExpressionNode( $2->code, $1->lineNumber(), $2->stringValue ); $$->Children.push_back( $1); $$->Children.push_back( $3); } | var ADD_ASSIGN expression { - $$ = new Node( $2->code, $1->lineNumber(), $2->stringValue ); + $$ = new ExpressionNode( $2->code, $1->lineNumber(), $2->stringValue ); $$->Children.push_back( $1); $$->Children.push_back( $3); } | var SUB_ASSIGN expression { - $$ = new Node( $2->code, $1->lineNumber(), $2->stringValue ); + $$ = new ExpressionNode( $2->code, $1->lineNumber(), $2->stringValue ); $$->Children.push_back( $1); $$->Children.push_back( $3); } | var MUL_ASSIGN expression { - $$ = new Node( $2->code, $1->lineNumber(), $2->stringValue ); + $$ = new ExpressionNode( $2->code, $1->lineNumber(), $2->stringValue ); $$->Children.push_back( $1); $$->Children.push_back( $3); } | var DIV_ASSIGN expression { - $$ = new Node( $2->code, $1->lineNumber(), $2->stringValue ); + $$ = new ExpressionNode( $2->code, $1->lineNumber(), $2->stringValue ); $$->Children.push_back( $1); $$->Children.push_back( $3); } | simpexp - { $$ = $1; } + { + $$ = new ExpressionNode( $1->tokenType(), $1->lineNumber(), $1->label() ); + $$->Children.push_back( $1 ); + } ; simpexp : simpexp logop relexp @@ -661,19 +667,19 @@ var : IDENT constant : NUMBER { - $$ = new Node( NUMBER, $1->line, $1->stringValue ); + $$ = new ConstantNode( NUMBER, $1->line, $1->stringValue ); } | NUMBER ':' primative_type { - $$ = new Node( NUMBER, $1->line, $1->stringValue ); + $$ = new ConstantNode( NUMBER, $1->line, $1->stringValue, $primative_type->code ); } | TRUE { - $$ = new Node( $1->code, $1->line, $1->stringValue ); + $$ = new ConstantNode( $1->code, $1->line, $1->stringValue, BOOL ); } | FALSE { - $$ = new Node( $1->code, $1->line, $1->stringValue ); + $$ = new ConstantNode( $1->code, $1->line, $1->stringValue, BOOL ); } ; @@ -701,11 +707,11 @@ str_params : simpexp ',' str_params str_literal : STRING_DBL { - $$ = new Node( $1->code, $1->line, $1->stringValue ); + $$ = new ConstantNode( $1->code, $1->line, $1->stringValue, STR ); } | STRING_TICK { - $$ = new Node( $1->code, $1->line, $1->stringValue ); + $$ = new ConstantNode( $1->code, $1->line, $1->stringValue, STR ); } ; diff --git a/Parser/scanner.lex b/Parser/scanner.lex index 188030e..2dbcdc8 100644 --- a/Parser/scanner.lex +++ b/Parser/scanner.lex @@ -541,6 +541,15 @@ s->stringValue = "f64"; return F64; } +"bool" { + lineNo = yylineno; + LexToken * s = new LexToken; + yylval.tokInfo = s; + s->code = BOOL; + s->line = yylineno; + s->stringValue = "bool"; + return BOOL; +} "str" { lineNo = yylineno; LexToken * s = new LexToken; diff --git a/Scripts/scanner.py b/Scripts/scanner.py index 055f6bf..2b08a0a 100644 --- a/Scripts/scanner.py +++ b/Scripts/scanner.py @@ -77,6 +77,7 @@ def data(): {"rule": "U128"}, {"rule": "F32"}, {"rule": "F64"}, + {"rule": "BOOL"}, {"rule": "STR"}, {"rule": "VEC"}, {"rule": "HASH"},