Skip to content
This repository was archived by the owner on Jun 7, 2020. It is now read-only.

Commit

Permalink
Merge branch 'develop' into feature/global-extension
Browse files Browse the repository at this point in the history
# Conflicts:
#	rozsireni
#	src/code_constructor.c
#	src/code_constructor.h
#	src/parser.c
#	test/parser.cpp
  • Loading branch information
thejoeejoee committed Nov 12, 2017
2 parents 7c5a77c + 7abb6e3 commit a450e00
Show file tree
Hide file tree
Showing 15 changed files with 378 additions and 73 deletions.
146 changes: 87 additions & 59 deletions doc/ll.txt
Original file line number Diff line number Diff line change
@@ -1,84 +1,112 @@
// Celý program
<prog> -> <body> <eols> EOF
<body> -> <definitions> <statement_scope>
<body> -> <definitions> <scope> <shared_variables_declarations>
<scope> -> SCOPE EOL <eols> <body_statements> END SCOPE

// Definiční část
<definitions> -> <eols> <definition> EOL <eols> <definitions>
<definitions> -> <eols> <definition> <definitions>
<definitions> -> <eols> E

<definition> -> <function_declaration>
<definition> -> <function_definition>
<definition> -> <shared_variable_declaration>

// Deklarace a definice funcí
<function_definition> -> <function_header> EOL <eols> <statements> END FUNCTION
<function_declaration> -> DECLARE <function_header> EOL <eols>
<function_definition> -> <function_header> EOL <eols> <function_statements> END FUNCTION

<function_header> -> FUNCTION IDENTIFIER (<function_params>) AS TYPE
<function_header> -> FUNCTION IDENTIFIER (<function_params>) AS <type>

<function_params> -> E
<function_params> -> <function_param> <function_n_param>

<function_n_param> -> E
<function_n_param> -> , <function_param> <function_n_param>
<function_param> -> <id> AS <type>
<function_n_param> -> <function_param> <function_n_param>

// Příkazy ve funkcí
<function_statements> -> E
<function_statements> -> <function_statement_single> EOL <eols> <statements>
<function_param> -> IDENTIFIER AS TYPE

// Příkazy ve scope
<body_statements> -> E
<body_statements> -> <body_statement_single> EOL <eols> <statements>

// Použitelné v těle funkce
<function_statement_single> -> <statement_assigment>
<function_statement_single> -> <statement_input>
<function_statement_single> -> <statement_print>
<function_statement_single> -> <statement_return>
<function_statement_single> -> <statement_scope>

// Použitelné ve scope
<body_statement_single> -> <statement_assigment>
<body_statement_single> -> <statement_input>
<body_statement_single> -> <statement_print>
<body_statement_single> -> <statement_5>
<body_statement_single> -> <statement_scope>

<statement_assigment> -> <id> EQUAL <expression> // přiřazení
<statement_input> -> INPUT IDENTIFIER // načtení ze vstupu
<statement_print> -> PRINT <print_expression> <print_expressions> // tisk na výstup, alespoň jeden příkaz, každý se středníkem
<statement_return> -> RETURN <expression>
<statement_5> -> <print_expression> // TODO nevíme, spekulativní
<statement_scope> -> SCOPE EOL <body_statements> END SCOPE

// Tisk řetězce
<print_expression> -> <expression> SEMICOLON
<print_expressions> -> E
<print_expressions> -> <print_expression> <print_expressions>

// Deklarace proměnné
<variable_declaration> -> DIM <id> AS <type> <declaration_assigment>
<body_statements> -> <body_statement_single> EOL <eols> <body_statements>

<function_statements> -> E
<function_statements> -> <function_statement_single> EOL <eols> <function_statements>

<cycle_statements> -> E
<cycle_statements> -> <cycle_statement_single> EOL <eols> <cycle_statements>

<function_statement_single> -> <identifier_assignment>
<function_statement_single> -> <input>
<function_statement_single> -> <return>
<function_statement_single> -> <print>
<function_statement_single> -> <condition>
<function_statement_single> -> <while_>
<function_statement_single> -> <variable_declaration>
<function_statement_single> -> <static_variable_declaration>
<function_statement_single> -> <for>

<body_statement_single> -> <input>
<body_statement_single> -> <identifier_assignment>
<body_statement_single> -> <while_>
<body_statement_single> -> <print>
<body_statement_single> -> <scope>
<body_statement_single> -> <condition>
<body_statement_single> -> <variable_declaration>
<function_statement_single> -> <for>

<cycle_statement_single> -> <identifier_assignment>
<cycle_statement_single> -> <input>
<cycle_statement_single> -> <for>
<cycle_statement_single> -> <return>
<cycle_statement_single> -> <print>
<cycle_statement_single> -> <condition>
<cycle_statement_single> -> <while_>
<cycle_statement_single> -> <variable_declaration>
<cycle_statement_single> -> <continue>
<cycle_statement_single> -> <exit>

<variable_declaration> -> DIM IDENTIFIER AS <type> <declaration_assignment>
<declaration_assignment> -> E
<declaration_assignment> -> <assignment>
<type> -> INTEGER
<type> -> BOOLEAN
<type> -> STRING
<type> -> DOUBLE

<identifier_assignment> -> IDENTIF <assignment>

<assignment> -> = <expression>
<assignment> -> <modify_assignment>

<shared_variables_declarations> -> E
<shared_variables_declarations> -> <shared_variable_declaration>
<shared_variable_declaration> -> DIM SHARED IDENTIFIER AS <type> <declaration_assignment>

<static_variable_declaration> -> STATIC IDENTIFIER AS <type> <declaration_assignment>

<return> -> RETURN <expr>

<assignment> -> <modify> <expression>
<modify> -> +=
<modify> -> -=
<modify> -> *=
<modify> -> /=
<modify> -> \=

<print> -> PRINT <print_expression> <print_expressions>
<print_expressions> -> E
<print_expressions> -> <print_expression> <print_expressions>
<print_expression> -> <expression> SEMICOLON

<while_> -> DO WHILE <expression> EOL <eols> <cycle_statements> LOOP

<input> -> INPUT IDENTIFIER

// podmínky
<condition> -> IF <expression> THEN EOL <eols> <statements> <else_section> END IF
<else_section> -> E
<else_section> -> ELSE EOL <eols> <statements>
<do_while> -> DO WHILE <expression> EOL <eols> <statements> LOOP
<condition> -> IF <expr> THEN EOL <eols> <statements>
<condition_elseif> <condition_else> END IF
<condition_elseif> -> E
<condition_elseif> -> ELSEIF <expr> THEN EOL <statements> <condition_elseif>

// volání funkce (pravidlo volané z expression kvůli rekurzi)
<function> = IDENTIFIER (<function_args>)
<function_args> -> E
<function_args> -> <function_arg> <function_n_arg>
<function_n_arg> -> E
<function_n_arg> -> , <function_arg> <function_n_arg>
<function_arg> -> <expression>
<condition_else> -> E
<condition_else> -> ELSE EOL <eols> <statements>

// Todo: Bonusové zadání, for
<for> -> FOR <id> EQUAL <expression> TO <expression> <step>.....?
<for> -> FOR IDENTIFIER <assignment> <step> EOL <eols> <cycle_statements> NEXT

<type> ->
<eols> -> E
<eols> -> EOL <eols>
<eols> -> EOL <eols>
1 change: 1 addition & 0 deletions rozsireni
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ FUNEXP
IFTHEN
SCOPE
BASE
BOOLOP
UNARY
GLOBAL
1 change: 0 additions & 1 deletion src/code_instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ CodeInstruction* code_instruction_init(

void code_instruction_free(CodeInstruction** instruction);


char* code_instruction_render(CodeInstruction* instruction);

#endif //_INSTRUCTION_H
6 changes: 6 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
#define GET_OVERLOADED_MACRO1234(_1, _2, _3, _4, ...) MSVC_EXPAND(GET_FIRST_ARG(__VA_ARGS__, 0))
#define GET_OVERLOADED_MACRO12345(_1, _2, _3, _4, _5, ...) MSVC_EXPAND(GET_FIRST_ARG(__VA_ARGS__, 0))

/**
* @brief Copy string (native c) and get pointer for it
*
* @param char* input string
* @return char* copy of the string
*/
char* c_string_copy(const char* string);

/**
Expand Down
1 change: 1 addition & 0 deletions src/lexer_fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "char_stack.h"
#include "dynamic_string.h"

// Lenght of lexer buffer
#define LEXER_FSM_STREAM_BUFFER_DEFAULT_LENGTH 2

/**
Expand Down
19 changes: 18 additions & 1 deletion src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,7 +1105,24 @@ bool parser_parse_assignment(Parser* parser) {
DataType expression_data_type;
SymbolVariable* actual_variable = parser->parser_semantic->actual_variable;
RULES(
// Todo: for tokens +=, -=, /= .... call rule modify_assignment and return value
CONDITIONAL_RULES(
lexer_rewind_token(parser->lexer, token);

CHECK_RULE(
token_type == TOKEN_ASSIGN_SUB || token_type == TOKEN_ASSIGN_ADD ||
token_type == TOKEN_ASSIGN_DIVIDE || token_type == TOKEN_ASSIGN_MULTIPLY ||
token_type == TOKEN_ASSIGN_INT_DIVIDE,
modify_assignment,
BEFORE({}),
AFTER(
{
token_free(&token);
return true;
}
)
);
);

CHECK_TOKEN(TOKEN_EQUAL);
CALL_EXPRESSION_RULE(expression_data_type);
);
Expand Down
13 changes: 9 additions & 4 deletions src/parser_expr_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ ExprToken* load_expr_token(Lexer* lexer, Token* last_token) {
expr_t->data.s = c_string_copy(last_token->data);
break;
// Literals
case TOKEN_TRUE:
expr_t->type = EXPR_TOKEN_BOOLEAN_LITERAL;
expr_t->data.b = true;
break;
case TOKEN_FALSE:
expr_t->type = EXPR_TOKEN_BOOLEAN_LITERAL;
expr_t->data.b = false;
break;
case TOKEN_DOUBLE_LITERAL:
expr_t->type = EXPR_TOKEN_DOUBLE_LITERAL;
expr_t->data.s = c_string_copy(last_token->data);
Expand Down Expand Up @@ -164,7 +172,6 @@ ExprToken* load_expr_token(Lexer* lexer, Token* last_token) {
void expr_token_free(ExprToken* t) {
if(t != NULL) {
if((t->type == EXPR_TOKEN_IDENTIFIER ||
t->type == EXPR_TOKEN_BOOLEAN_LITERAL ||
t->type == EXPR_TOKEN_INTEGER_LITERAL ||
t->type == EXPR_TOKEN_DOUBLE_LITERAL ||
t->type == EXPR_TOKEN_STRING_LITERAL
Expand All @@ -187,11 +194,9 @@ int expr_llist_type_cmp(LListBaseItem* a, LListBaseItem* b) {

void expr_llist_free(LListBaseItem* item) {
ASSERT(item != NULL);
ExprToken* t = (ExprToken*) item;

ExprToken* t = (ExprToken*)item;
if(t != NULL) {
if((t->type == EXPR_TOKEN_IDENTIFIER ||
t->type == EXPR_TOKEN_BOOLEAN_LITERAL ||
t->type == EXPR_TOKEN_INTEGER_LITERAL ||
t->type == EXPR_TOKEN_DOUBLE_LITERAL ||
t->type == EXPR_TOKEN_STRING_LITERAL
Expand Down
1 change: 1 addition & 0 deletions src/parser_expr_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef unsigned ExprIdx;
typedef union expr_data_u {
ExprIdx idx;
char* s;
bool b;
} ExprData;

typedef struct expr_token_t {
Expand Down
79 changes: 78 additions & 1 deletion src/parser_expr_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ const expression_rule_function expr_rule_table[EXPR_RULE_TABLE_SIZE] = {
expression_rule_div,
expression_rule_div_int,
expression_rule_unary_minus,
expression_rule_not,
expression_rule_and,
expression_rule_or,
expression_rule_greater,
expression_rule_greater_or_equal,
expression_rule_equal,
Expand Down Expand Up @@ -125,7 +128,7 @@ bool expression_rule_id(Parser* parser, LList* expr_token_buffer, ExprIdx* expre
i->data_type = DATA_TYPE_BOOLEAN;

CodeConstructor* constructor = parser->code_constructor;
GENERATE_CODE(I_PUSH_STACK, code_instruction_operand_init_boolean(0 == strcmp(i->data.s, "true")));
GENERATE_CODE(I_PUSH_STACK, code_instruction_operand_init_boolean(i->data.b));

} else if(i->type == EXPR_TOKEN_IDENTIFIER) {
SymbolVariable* variable = symbol_register_find_variable_recursive(
Expand Down Expand Up @@ -851,3 +854,77 @@ bool expression_rule_fn_chr(Parser* parser, LList* expr_token_buffer, ExprIdx* e
return true;

}

bool expression_rule_not(Parser* parser, LList* expr_token_buffer, ExprIdx* expression_idx)
{
/*
* RULE
* E -> NOT E
*/

// NOTE: we are processing rule backwards!
EXPR_RULE_CHECK_START();
EXPR_RULE_CHECK_TYPE(EXPR_EXPRESSION);
EXPR_RULE_CHECK_TYPE(EXPR_TOKEN_NOT);
EXPR_RULE_CHECK_FINISH();
EXPR_CHECK_UNARY_OPERATION_IMPLICIT_CONVERSION(OPERATION_NOT);

// NOTE: now we are processing rule regular way - from the left to the right

CODE_GENERATION(
{
CodeConstructor* constructor = parser->code_constructor;
GENERATE_CODE(I_NOT_STACK);
}
);

ExprToken* e = create_expression((*expression_idx)++);
e->data_type = DATA_TYPE_BOOLEAN;
EXPR_RULE_REPLACE(e);
return true;
}

bool expression_rule_and(Parser* parser, LList *expr_token_buffer, ExprIdx* expression_idx) {
/*
* RULE
* E -> E AND E
*/
// backward
EXPR_RULE_CHECK_START();
EXPR_RULE_CHECK_TYPE(EXPR_EXPRESSION);
EXPR_RULE_CHECK_TYPE(EXPR_TOKEN_AND);
EXPR_RULE_CHECK_TYPE(EXPR_EXPRESSION);
EXPR_RULE_CHECK_FINISH();
EXPR_CHECK_BINARY_OPERATION_IMPLICIT_CONVERSION(OPERATION_AND);

CREATE_EXPR_RESULT_OF_BINARY_OPERATION(OPERATION_AND);

CodeConstructor* constructor = parser->code_constructor;
GENERATE_IMPLICIT_CONVERSIONS_FOR_BINARY_OPERATION_SIGNATURE();
GENERATE_CODE(I_AND_STACK);

EXPR_RULE_REPLACE(e);
return true;
}
bool expression_rule_or(Parser* parser, LList *expr_token_buffer, ExprIdx* expression_idx) {
/*
* RULE
* E -> E OR E
*/
// backward
EXPR_RULE_CHECK_START();
EXPR_RULE_CHECK_TYPE(EXPR_EXPRESSION);
EXPR_RULE_CHECK_TYPE(EXPR_TOKEN_OR);
EXPR_RULE_CHECK_TYPE(EXPR_EXPRESSION);
EXPR_RULE_CHECK_FINISH();
EXPR_CHECK_BINARY_OPERATION_IMPLICIT_CONVERSION(OPERATION_OR);

CREATE_EXPR_RESULT_OF_BINARY_OPERATION(OPERATION_OR);

CodeConstructor* constructor = parser->code_constructor;
GENERATE_IMPLICIT_CONVERSIONS_FOR_BINARY_OPERATION_SIGNATURE();
GENERATE_CODE(I_OR_STACK);

EXPR_RULE_REPLACE(e);
return true;
}
Loading

0 comments on commit a450e00

Please sign in to comment.