add declaring and assignment with parser LHS support
This commit is contained in:
4
.vscode/c_cpp_properties.json
vendored
4
.vscode/c_cpp_properties.json
vendored
@@ -3,8 +3,8 @@
|
|||||||
{
|
{
|
||||||
"name": "Linux",
|
"name": "Linux",
|
||||||
"compilerPath": "/usr/bin/clang",
|
"compilerPath": "/usr/bin/clang",
|
||||||
"cStandard": "c99",
|
"cStandard": "C23",
|
||||||
"cppStandard": "c++99",
|
"cppStandard": "c++23",
|
||||||
"intelliSenseMode": "linux-clang-x64",
|
"intelliSenseMode": "linux-clang-x64",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"${workspaceFolder}/**"
|
"${workspaceFolder}/**"
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
#define GET_STATE LexerState *state = (LexerState *)yyget_extra(yyscanner);
|
#define GET_STATE LexerState *state = (LexerState *)yyget_extra(yyscanner);
|
||||||
#define COLUMN_NO state->current_column
|
#define COLUMN_NO state->current_column
|
||||||
|
|
||||||
int yywrap(void *) {
|
int yywrap(void * unused_param) {
|
||||||
|
(void)unused_param;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
@@ -18,7 +19,6 @@ int yywrap(void *) {
|
|||||||
"," { return TOKEN_COMMA; }
|
"," { return TOKEN_COMMA; }
|
||||||
":" { return TOKEN_COLON; }
|
":" { return TOKEN_COLON; }
|
||||||
|
|
||||||
|
|
||||||
"=" { return TOKEN_ASSIGN; }
|
"=" { return TOKEN_ASSIGN; }
|
||||||
"+=" { return TOKEN_ASSIGN_PLUS; }
|
"+=" { return TOKEN_ASSIGN_PLUS; }
|
||||||
"-=" { return TOKEN_ASSIGN_MINUS; }
|
"-=" { return TOKEN_ASSIGN_MINUS; }
|
||||||
@@ -47,7 +47,7 @@ int yywrap(void *) {
|
|||||||
|
|
||||||
|
|
||||||
"if" { return TOKEN_IF; }
|
"if" { return TOKEN_IF; }
|
||||||
"else if" { return TOKEN_ELSE_IF; }
|
"else"[ \t]+"if" { return TOKEN_ELSE_IF; }
|
||||||
"else" { return TOKEN_ELSE; }
|
"else" { return TOKEN_ELSE; }
|
||||||
"while" { return TOKEN_WHILE; }
|
"while" { return TOKEN_WHILE; }
|
||||||
"forever" { return TOKEN_FOREVER; }
|
"forever" { return TOKEN_FOREVER; }
|
||||||
|
|||||||
28
src/parser/assignable/access/access.c
Normal file
28
src/parser/assignable/access/access.c
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#include "access.h"
|
||||||
|
#include "../../../lexer/token.h"
|
||||||
|
#include "../../parser.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "../../../memory.h"
|
||||||
|
|
||||||
|
ParsedValue *parse_access(char*file,DArray *tokens, size_t * index, ParsedValue * to_access) {
|
||||||
|
(*index)++;
|
||||||
|
error_if_finished(file, tokens, index);
|
||||||
|
Token * token = darray_get(tokens, *index);
|
||||||
|
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
|
||||||
|
ParsedAccess *parsedAccess = checked_malloc(sizeof(ParsedAccess));
|
||||||
|
parsedAccess->to_access = to_access;
|
||||||
|
parsedAccess->access = strcpy(checked_malloc(sizeof(token->value)), token->value);
|
||||||
|
parsedValue->type = AST_ACCESS;
|
||||||
|
parsedValue->data = parsedAccess;
|
||||||
|
return parsedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_parse_access(void *ptr) {
|
||||||
|
ParsedValue *parsedValue = ptr;
|
||||||
|
ParsedAccess *parsedAccess = parsedValue->data;
|
||||||
|
free_parsed(parsedAccess->to_access);
|
||||||
|
free(parsedAccess->access);
|
||||||
|
free(parsedAccess->to_access);
|
||||||
|
free(parsedAccess);
|
||||||
|
}
|
||||||
16
src/parser/assignable/access/access.h
Normal file
16
src/parser/assignable/access/access.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef ACCESS_H
|
||||||
|
#define ACCESS_H
|
||||||
|
#include "../../parser.h"
|
||||||
|
#include "../../../lexer/token.h" // for Token
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ParsedValue * to_access;
|
||||||
|
char * access;
|
||||||
|
} ParsedAccess;
|
||||||
|
|
||||||
|
// Function declaration for parsing an identifier
|
||||||
|
ParsedValue *parse_access(char*file,DArray *tokens, size_t * index, ParsedValue * to_access);
|
||||||
|
|
||||||
|
void free_parse_access(void *ptr);
|
||||||
|
|
||||||
|
#endif // ACCESS_H
|
||||||
@@ -1,21 +1,14 @@
|
|||||||
#include "assign.h"
|
#include "assign.h"
|
||||||
#include "../../lexer/token.h"
|
#include "../../../lexer/token.h"
|
||||||
#include "../parser.h"
|
#include "../../parser.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "../../memory.h"
|
#include "../../../memory.h"
|
||||||
|
|
||||||
ParsedValue *parse_assign(char *file, DArray *parsed, DArray *tokens,
|
ParsedValue *parse_assign(char *file, DArray *tokens,
|
||||||
ParsedValue *assign_to, size_t *index) {
|
ParsedValue *assign_to, size_t *index) {
|
||||||
bool islet = false;
|
|
||||||
Token *token = darray_get(tokens, *index);
|
Token *token = darray_get(tokens, *index);
|
||||||
if (token->type == TOKEN_LET) {
|
|
||||||
islet = true;
|
|
||||||
(*index)++;
|
|
||||||
error_if_finished(file,tokens,index);
|
|
||||||
token = darray_get(tokens, *index);
|
|
||||||
}
|
|
||||||
switch (assign_to->type) {
|
switch (assign_to->type) {
|
||||||
case AST_IDENTIFIER:
|
case AST_IDENTIFIER:
|
||||||
case AST_ASSIGN:
|
case AST_ASSIGN:
|
||||||
@@ -31,8 +24,7 @@ ParsedValue *parse_assign(char *file, DArray *parsed, DArray *tokens,
|
|||||||
(*index)++;
|
(*index)++;
|
||||||
error_if_finished(file,tokens,index);
|
error_if_finished(file,tokens,index);
|
||||||
token = darray_get(tokens, *index);
|
token = darray_get(tokens, *index);
|
||||||
assign->from = parse_token(file, parsed, tokens, index, true);
|
assign->from = parse_token(file, tokens, index, true);
|
||||||
assign->let = islet;
|
|
||||||
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
|
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
|
||||||
parsedValue->type = AST_ASSIGN;
|
parsedValue->type = AST_ASSIGN;
|
||||||
parsedValue->data = assign;
|
parsedValue->data = assign;
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
#ifndef ASSIGN_H
|
#ifndef ASSIGN_H
|
||||||
#define ASSIGN_H
|
#define ASSIGN_H
|
||||||
#include "../parser.h"
|
#include "../../parser.h"
|
||||||
#include "../../lexer/token.h"
|
#include "../../../lexer/token.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool let;
|
|
||||||
ParsedValue * to;
|
ParsedValue * to;
|
||||||
TokenType type;
|
TokenType type;
|
||||||
ParsedValue * from;
|
ParsedValue * from;
|
||||||
} ParsedAssign;
|
} ParsedAssign;
|
||||||
|
|
||||||
ParsedValue *parse_assign(char*file,DArray *parsed, DArray *tokens,
|
ParsedValue *parse_assign(char*file, DArray *tokens,
|
||||||
ParsedValue *assign_to, size_t *index);
|
ParsedValue *assign_to, size_t *index);
|
||||||
|
|
||||||
void free_parse_assign(void*ptr);
|
void free_parse_assign(void*ptr);
|
||||||
59
src/parser/assignable/call/call.c
Normal file
59
src/parser/assignable/call/call.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#include "call.h"
|
||||||
|
#include "../../../lexer/token.h"
|
||||||
|
#include "../../../memory.h"
|
||||||
|
#include "../../parser.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
ParsedValue *parse_call(char *file, DArray *tokens, size_t *index,
|
||||||
|
ParsedValue *to_call) {
|
||||||
|
(*index)++;
|
||||||
|
error_if_finished(file, tokens, index);
|
||||||
|
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
|
||||||
|
ParsedCall *parsedCall = checked_malloc(sizeof(ParsedCall));
|
||||||
|
DArray *args = checked_malloc(sizeof(DArray));
|
||||||
|
darray_init(args, sizeof(ParsedValue));
|
||||||
|
parsedCall->to_call = to_call;
|
||||||
|
parsedCall->args = args;
|
||||||
|
parsedValue->type = AST_ACCESS;
|
||||||
|
parsedValue->data = parsedCall;
|
||||||
|
Token *token = darray_get(tokens, *index);
|
||||||
|
DArray *arg = checked_malloc(sizeof(DArray));
|
||||||
|
darray_init(arg, sizeof(ParsedValue));
|
||||||
|
while (true) {
|
||||||
|
bool to_break = false;
|
||||||
|
switch (token->type) {
|
||||||
|
case TOKEN_RPAREN:
|
||||||
|
to_break = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (to_break)
|
||||||
|
break;
|
||||||
|
ParsedValue *parsedValue = parse_token(file, tokens, index, true);
|
||||||
|
darray_push(arg, parsedValue);
|
||||||
|
switch (token->type) {
|
||||||
|
case TOKEN_COMMA:
|
||||||
|
darray_push(args, arg);
|
||||||
|
arg = checked_malloc(sizeof(DArray));
|
||||||
|
darray_init(arg, sizeof(ParsedValue));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parsedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_parse_call(void *ptr) {
|
||||||
|
ParsedValue *parsedValue = ptr;
|
||||||
|
ParsedCall *parsedCall = parsedValue->data;
|
||||||
|
|
||||||
|
free_parsed(parsedCall->to_call);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
free(parsedCall);
|
||||||
|
}
|
||||||
16
src/parser/assignable/call/call.h
Normal file
16
src/parser/assignable/call/call.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef CALL_H
|
||||||
|
#define CALL_H
|
||||||
|
#include "../../parser.h"
|
||||||
|
#include "../../../lexer/token.h" // for Token
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ParsedValue * to_call;
|
||||||
|
DArray * args;
|
||||||
|
} ParsedCall;
|
||||||
|
|
||||||
|
// Function declaration for parsing an identifier
|
||||||
|
ParsedValue *parse_call(char *file, DArray *tokens, size_t *index,
|
||||||
|
ParsedValue *to_call);
|
||||||
|
void free_parse_call(void *ptr);
|
||||||
|
|
||||||
|
#endif // CALL_H
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "identifier.h"
|
#include "identifier.h"
|
||||||
#include "../../lexer/token.h"
|
#include "../../../lexer/token.h"
|
||||||
#include "../parser.h"
|
#include "../../parser.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "../../memory.h"
|
#include "../../../memory.h"
|
||||||
|
|
||||||
ParsedValue *parse_identifier(Token *token) {
|
ParsedValue *parse_identifier(Token *token) {
|
||||||
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
|
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#ifndef IDENTIFIER_H
|
#ifndef IDENTIFIER_H
|
||||||
#define IDENTIFIER_H
|
#define IDENTIFIER_H
|
||||||
#include "../parser.h"
|
#include "../../parser.h"
|
||||||
#include "../../lexer/token.h" // for Token
|
#include "../../../lexer/token.h" // for Token
|
||||||
|
|
||||||
// Function declaration for parsing an identifier
|
// Function declaration for parsing an identifier
|
||||||
ParsedValue * parse_identifier(Token * token);
|
ParsedValue * parse_identifier(Token * token);
|
||||||
30
src/parser/declaration/declaration.c
Normal file
30
src/parser/declaration/declaration.c
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#include "declaration.h"
|
||||||
|
#include "../../lexer/token.h"
|
||||||
|
#include "../../memory.h"
|
||||||
|
#include "../parser.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
ParsedValue *parse_declaration(char *file, DArray *parsed, DArray *tokens,
|
||||||
|
size_t *index) {
|
||||||
|
(*index)++;
|
||||||
|
error_if_finished(file, tokens, index);
|
||||||
|
Token *token = darray_get(tokens, *index);
|
||||||
|
|
||||||
|
ParsedValue * parsedValue = malloc(sizeof(ParsedValue));
|
||||||
|
ParsedDeclaration * declaration = malloc(sizeof(ParsedDeclaration));
|
||||||
|
parsedValue->data = declaration;
|
||||||
|
parsedValue->type = AST_DECLARATION;
|
||||||
|
|
||||||
|
if (token->type != TOKEN_IDENTIFIER) {
|
||||||
|
fprintf(stderr, "%s:%u:%u error: declaration requires an identifier\n",
|
||||||
|
file, token->line, token->column);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
declaration->name = strcpy(checked_malloc(sizeof(token->value)), token->value);
|
||||||
|
(*index)++;
|
||||||
|
if ((*index) >= tokens->size) return parsedValue;
|
||||||
|
token = darray_get(tokens, *index);
|
||||||
|
return parsedValue;
|
||||||
|
}
|
||||||
16
src/parser/declaration/declaration.h
Normal file
16
src/parser/declaration/declaration.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef DECLARATION_H
|
||||||
|
#define DECLARATION_H
|
||||||
|
#include "../parser.h"
|
||||||
|
#include "../../lexer/token.h" // for Token
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char * name;
|
||||||
|
bool is_function;
|
||||||
|
DArray args; // string[]
|
||||||
|
ParsedValue * from;
|
||||||
|
} ParsedDeclaration;
|
||||||
|
|
||||||
|
// Function declaration for parsing an identifier
|
||||||
|
ParsedValue *parse_declaration(char *file, DArray *parsed, DArray *tokens, size_t *index);
|
||||||
|
|
||||||
|
#endif // DECLARATION_H
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "../../memory.h"
|
#include "../../memory.h"
|
||||||
|
|
||||||
ParsedValue *parse_if(char *file, DArray *parsed, DArray *tokens,
|
ParsedValue *parse_if(char *file, DArray *tokens,
|
||||||
size_t *index) {
|
size_t *index) {
|
||||||
(*index)++;
|
(*index)++;
|
||||||
error_if_finished(file, tokens, index);
|
error_if_finished(file, tokens, index);
|
||||||
@@ -54,7 +54,7 @@ ParsedValue *parse_if(char *file, DArray *parsed, DArray *tokens,
|
|||||||
darray_init(condition, sizeof(ParsedValue));
|
darray_init(condition, sizeof(ParsedValue));
|
||||||
|
|
||||||
while (*index < tokens->size) {
|
while (*index < tokens->size) {
|
||||||
ParsedValue *parsed_code = parse_token(file, parsed, tokens, index, true);
|
ParsedValue *parsed_code = parse_token(file, tokens, index, true);
|
||||||
if (parsed_code) {
|
if (parsed_code) {
|
||||||
darray_push(condition, parsed_code);
|
darray_push(condition, parsed_code);
|
||||||
free(parsed_code);
|
free(parsed_code);
|
||||||
@@ -78,7 +78,7 @@ ParsedValue *parse_if(char *file, DArray *parsed, DArray *tokens,
|
|||||||
|
|
||||||
// Parse the body
|
// Parse the body
|
||||||
ParsedValue *parsed_content =
|
ParsedValue *parsed_content =
|
||||||
parse_token(file, parsed, tokens, index, false);
|
parse_token(file, tokens, index, false);
|
||||||
|
|
||||||
if (!parsed_content) {
|
if (!parsed_content) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@@ -120,6 +120,7 @@ void free_conditional(void *ptr) {
|
|||||||
if (conditional->condition)
|
if (conditional->condition)
|
||||||
darray_free(conditional->condition, free_parsed);
|
darray_free(conditional->condition, free_parsed);
|
||||||
free_parsed(conditional->content);
|
free_parsed(conditional->content);
|
||||||
|
free(conditional->content);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_parsed_if(void *ptr) {
|
void free_parsed_if(void *ptr) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ typedef struct {
|
|||||||
ParsedValue *content;
|
ParsedValue *content;
|
||||||
} ParsedConditional;
|
} ParsedConditional;
|
||||||
|
|
||||||
ParsedValue *parse_if(char *file, DArray *parsed, DArray *tokens,
|
ParsedValue *parse_if(char *file, DArray *tokens,
|
||||||
size_t *index);
|
size_t *index);
|
||||||
|
|
||||||
void free_parsed_if(void *ptr);
|
void free_parsed_if(void *ptr);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "../dynamic_array/darray.h"
|
#include "../dynamic_array/darray.h"
|
||||||
#include "../lexer/token.h"
|
#include "../lexer/token.h"
|
||||||
#include "assign/assign.h"
|
#include "assignable/assign/assign.h"
|
||||||
#include "identifier/identifier.h"
|
#include "assignable/identifier/identifier.h"
|
||||||
#include "if/if.h"
|
#include "if/if.h"
|
||||||
#include "number/number.h"
|
#include "number/number.h"
|
||||||
#include "string/string.h"
|
#include "string/string.h"
|
||||||
@@ -12,8 +12,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
const char *ValueTypeNames[] = {"string", "assign", "identifier", "number",
|
const char *ValueTypeNames[] = {"string", "assign", "identifier",
|
||||||
"if statement"};
|
"number", "if statement", "access",
|
||||||
|
"call"};
|
||||||
|
|
||||||
void error_if_finished(char *file, DArray *tokens, size_t *index) {
|
void error_if_finished(char *file, DArray *tokens, size_t *index) {
|
||||||
if ((*index) >= tokens->size) {
|
if ((*index) >= tokens->size) {
|
||||||
@@ -24,13 +25,16 @@ void error_if_finished(char *file, DArray *tokens, size_t *index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedValue *parse_token(char *file, DArray *parsed, DArray *tokens,
|
ParsedValue *parse_token(char *file, DArray *tokens,
|
||||||
size_t *index, bool inline_flag) {
|
size_t *index, bool inline_flag) {
|
||||||
Token *token = darray_get(tokens, *index);
|
Token *token = darray_get(tokens, *index);
|
||||||
|
|
||||||
|
ParsedValue * output = NULL;
|
||||||
|
|
||||||
if (!inline_flag) {
|
if (!inline_flag) {
|
||||||
switch (token->type) {
|
switch (token->type) {
|
||||||
case TOKEN_IF:
|
case TOKEN_IF:
|
||||||
return parse_if(file, parsed, tokens, index);
|
return parse_if(file, tokens, index);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
@@ -38,24 +42,37 @@ ParsedValue *parse_token(char *file, DArray *parsed, DArray *tokens,
|
|||||||
switch (token->type) {
|
switch (token->type) {
|
||||||
case TOKEN_STRING:
|
case TOKEN_STRING:
|
||||||
(*index)++;
|
(*index)++;
|
||||||
return parse_string(*token);
|
output = parse_string(*token);
|
||||||
|
break;
|
||||||
case TOKEN_NEW_LINE:
|
case TOKEN_NEW_LINE:
|
||||||
while (token->type == TOKEN_NEW_LINE && ++(*index) < tokens->size) {
|
while (token->type == TOKEN_NEW_LINE && ++(*index) < tokens->size) {
|
||||||
token = darray_get(tokens, *index);
|
token = darray_get(tokens, *index);
|
||||||
}
|
}
|
||||||
if (token->type == TOKEN_NEW_LINE)
|
if (token->type == TOKEN_NEW_LINE)
|
||||||
return NULL;
|
break;
|
||||||
return parse_token(file, parsed, tokens, index, inline_flag);
|
output = parse_token(file, tokens, index, inline_flag);
|
||||||
|
break;
|
||||||
case TOKEN_INDENT:
|
case TOKEN_INDENT:
|
||||||
fprintf(stderr, "%s:%u:%u error: invalid indentation\n", file, token->line,
|
fprintf(stderr, "%s:%u:%u error: invalid indentation\n", file, token->line,
|
||||||
token->column);
|
token->column);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
case TOKEN_LET:
|
case TOKEN_IDENTIFIER:
|
||||||
case TOKEN_IDENTIFIER:;
|
|
||||||
ParsedValue *assign_to = parse_identifier(token);
|
|
||||||
(*index)++;
|
(*index)++;
|
||||||
if (*index >= tokens->size)
|
output = parse_identifier(token);
|
||||||
return assign_to;
|
break;
|
||||||
|
case TOKEN_NUMBER:
|
||||||
|
(*index)++;
|
||||||
|
output = parse_number(token);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "%s:%u:%u error: syntax error\n", file, token->line,
|
||||||
|
token->column);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LHS required
|
||||||
|
bool passed = false;
|
||||||
|
while (!passed && (*index) < tokens->size) {
|
||||||
token = darray_get(tokens, *index);
|
token = darray_get(tokens, *index);
|
||||||
switch (token->type) {
|
switch (token->type) {
|
||||||
case TOKEN_ASSIGN:
|
case TOKEN_ASSIGN:
|
||||||
@@ -66,43 +83,21 @@ ParsedValue *parse_token(char *file, DArray *parsed, DArray *tokens,
|
|||||||
case TOKEN_ASSIGN_PLUS:
|
case TOKEN_ASSIGN_PLUS:
|
||||||
case TOKEN_ASSIGN_SLASH:
|
case TOKEN_ASSIGN_SLASH:
|
||||||
case TOKEN_ASSIGN_STAR:;
|
case TOKEN_ASSIGN_STAR:;
|
||||||
DArray slice = darray_slice(parsed, parsed->size, parsed->size);
|
output = parse_assign(file, tokens, output, index);
|
||||||
return parse_assign(file, &slice, tokens, assign_to, index);
|
break;
|
||||||
default:
|
default:
|
||||||
return assign_to;
|
passed = true;
|
||||||
}
|
}
|
||||||
case TOKEN_ASSIGN:
|
|
||||||
case TOKEN_ASSIGN_CARET:
|
|
||||||
case TOKEN_ASSIGN_FLOORDIV:
|
|
||||||
case TOKEN_ASSIGN_MINUS:
|
|
||||||
case TOKEN_ASSIGN_MODULO:
|
|
||||||
case TOKEN_ASSIGN_PLUS:
|
|
||||||
case TOKEN_ASSIGN_SLASH:
|
|
||||||
case TOKEN_ASSIGN_STAR:
|
|
||||||
if (parsed->size == 0) {
|
|
||||||
fprintf(stderr, "%s:%u:%u error: syntax error\n", file, token->line,
|
|
||||||
token->column);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
ParsedValue *assigning_to = darray_get(parsed, parsed->size - 1);
|
|
||||||
fprintf(stderr, "%s:%u:%u error: cannot assign to %s\n", file, token->line,
|
|
||||||
token->column, ValueTypeNames[assigning_to->type]);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
case TOKEN_NUMBER:
|
|
||||||
(*index)++;
|
|
||||||
return parse_number(token);
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "%s:%u:%u error: syntax error\n", file, token->line,
|
|
||||||
token->column);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) {
|
void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) {
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
while (index < tokens->size) {
|
while (index < tokens->size) {
|
||||||
ParsedValue *parsed_code =
|
ParsedValue *parsed_code =
|
||||||
parse_token(file, parsed, tokens, &index, inline_flag);
|
parse_token(file, tokens, &index, inline_flag);
|
||||||
if (parsed_code) {
|
if (parsed_code) {
|
||||||
darray_push(parsed, parsed_code);
|
darray_push(parsed, parsed_code);
|
||||||
free(parsed_code);
|
free(parsed_code);
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ typedef enum {
|
|||||||
AST_IDENTIFIER,
|
AST_IDENTIFIER,
|
||||||
AST_NUMBER,
|
AST_NUMBER,
|
||||||
AST_IF,
|
AST_IF,
|
||||||
|
AST_ACCESS,
|
||||||
|
AST_CALL,
|
||||||
|
AST_DECLARATION
|
||||||
} ValueType;
|
} ValueType;
|
||||||
|
|
||||||
extern const char* ValueTypeNames[];
|
extern const char* ValueTypeNames[];
|
||||||
@@ -24,7 +27,7 @@ typedef struct {
|
|||||||
|
|
||||||
void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag);
|
void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag);
|
||||||
|
|
||||||
ParsedValue *parse_token(char *file, DArray *parsed, DArray *tokens,
|
ParsedValue *parse_token(char *file, DArray *tokens,
|
||||||
size_t *index, bool inline_flag);
|
size_t *index, bool inline_flag);
|
||||||
|
|
||||||
void free_parsed(void *ptr);
|
void free_parsed(void *ptr);
|
||||||
|
|||||||
Reference in New Issue
Block a user