add do wraps
This commit is contained in:
@@ -62,7 +62,7 @@ void darray_pop(DArray *arr, void (*free_data)(void *)) {
|
|||||||
free_data(target);
|
free_data(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
darray_resize(arr, arr->size);
|
darray_resize(arr, arr->size-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *darray_get(DArray *arr, size_t index) {
|
void *darray_get(DArray *arr, size_t index) {
|
||||||
@@ -106,4 +106,5 @@ void darray_free(DArray *arr, void (*free_data)(void *)) {
|
|||||||
arr->size = 0;
|
arr->size = 0;
|
||||||
arr->capacity = 0;
|
arr->capacity = 0;
|
||||||
arr->element_size = 0;
|
arr->element_size = 0;
|
||||||
|
arr->resizable = false;
|
||||||
}
|
}
|
||||||
@@ -86,14 +86,10 @@ int yywrap(void * unused_param) {
|
|||||||
return TOKEN_STRING;
|
return TOKEN_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
((([0-9]+(\.[0-9]+)?)|(\.[0-9]+))(e((\-|\+)?([0-9]+(\.[0-9]+)?)))?) {
|
\-?((([0-9]+(\.[0-9]+)?)|(\.[0-9]+))(e((\-|\+)?([0-9]+(\.[0-9]+)?)))?) {
|
||||||
return TOKEN_NUMBER;
|
return TOKEN_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
([0-9]+\/[0-9]+) {
|
|
||||||
return TOKEN_FRACTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
\n { return TOKEN_NEW_LINE; }
|
\n { return TOKEN_NEW_LINE; }
|
||||||
|
|
||||||
[ \t]+ {
|
[ \t]+ {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ ParsedValue *parse_access(char*file,DArray *tokens, size_t * index, ParsedValue
|
|||||||
parsedAccess->access = strcpy(checked_malloc(strlen(token->value) + 1), token->value);
|
parsedAccess->access = strcpy(checked_malloc(strlen(token->value) + 1), token->value);
|
||||||
parsedValue->type = AST_ACCESS;
|
parsedValue->type = AST_ACCESS;
|
||||||
parsedValue->data = parsedAccess;
|
parsedValue->data = parsedAccess;
|
||||||
|
(*index)++;
|
||||||
return parsedValue;
|
return parsedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,7 @@ ParsedValue *parse_call(char *file, DArray *tokens, size_t *index,
|
|||||||
(*index)++;
|
(*index)++;
|
||||||
error_if_finished(file, tokens, index);
|
error_if_finished(file, tokens, index);
|
||||||
Token *token = darray_get(tokens, *index);
|
Token *token = darray_get(tokens, *index);
|
||||||
if (token->type == TOKEN_RPAREN) {
|
if (token->type != TOKEN_RPAREN) {
|
||||||
(*index)++;
|
|
||||||
if ((*index) >= tokens->size)
|
|
||||||
return parsedValue;
|
|
||||||
token = darray_get(tokens, *index);
|
|
||||||
} else {
|
|
||||||
while ((*index) < tokens->size) {
|
while ((*index) < tokens->size) {
|
||||||
skip_newlines_and_indents(tokens, index);
|
skip_newlines_and_indents(tokens, index);
|
||||||
error_if_finished(file, tokens, index);
|
error_if_finished(file, tokens, index);
|
||||||
@@ -35,10 +30,6 @@ ParsedValue *parse_call(char *file, DArray *tokens, size_t *index,
|
|||||||
error_if_finished(file, tokens, index);
|
error_if_finished(file, tokens, index);
|
||||||
token = darray_get(tokens, *index);
|
token = darray_get(tokens, *index);
|
||||||
if (token->type == TOKEN_RPAREN) {
|
if (token->type == TOKEN_RPAREN) {
|
||||||
(*index)++;
|
|
||||||
if ((*index) >= tokens->size)
|
|
||||||
break;
|
|
||||||
token = darray_get(tokens, *index);
|
|
||||||
break;
|
break;
|
||||||
} else if (token->type != TOKEN_COMMA) {
|
} else if (token->type != TOKEN_COMMA) {
|
||||||
fprintf(stderr, "%s:%zu:%zu error: expected comma\n", file, token->line,
|
fprintf(stderr, "%s:%zu:%zu error: expected comma\n", file, token->line,
|
||||||
@@ -49,6 +40,7 @@ ParsedValue *parse_call(char *file, DArray *tokens, size_t *index,
|
|||||||
error_if_finished(file, tokens, index);
|
error_if_finished(file, tokens, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(*index)++;
|
||||||
return parsedValue;
|
return parsedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) {
|
|||||||
error_if_finished(file, tokens, index);
|
error_if_finished(file, tokens, index);
|
||||||
Token *token = darray_get(tokens, *index);
|
Token *token = darray_get(tokens, *index);
|
||||||
|
|
||||||
ParsedValue *parsedValue = malloc(sizeof(ParsedValue));
|
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
|
||||||
parsedValue->type = AST_DECLARATION;
|
parsedValue->type = AST_DECLARATION;
|
||||||
DArray *declarations = malloc(sizeof(DArray));
|
DArray *declarations = checked_malloc(sizeof(DArray));
|
||||||
darray_init(declarations, sizeof(ParsedSingleDeclaration));
|
darray_init(declarations, sizeof(ParsedSingleDeclaration));
|
||||||
parsedValue->data = declarations;
|
parsedValue->data = declarations;
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -100,6 +100,10 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) {
|
|||||||
break;
|
break;
|
||||||
token = darray_get(tokens, *index);
|
token = darray_get(tokens, *index);
|
||||||
}
|
}
|
||||||
|
skip_newlines_and_indents(tokens, index);
|
||||||
|
if ((*index) >= tokens->size)
|
||||||
|
break;
|
||||||
|
token = darray_get(tokens, *index);
|
||||||
if (token->type != TOKEN_COMMA)
|
if (token->type != TOKEN_COMMA)
|
||||||
break;
|
break;
|
||||||
(*index)++;
|
(*index)++;
|
||||||
|
|||||||
104
src/parser/dowrap/dowrap.c
Normal file
104
src/parser/dowrap/dowrap.c
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
#include "../../lexer/token.h"
|
||||||
|
#include "../../memory.h"
|
||||||
|
#include "../parser.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
char *repeat_space(size_t x) {
|
||||||
|
|
||||||
|
char *str = checked_malloc(x + 1); // +1 for the null terminator
|
||||||
|
|
||||||
|
memset(str, ' ', x);
|
||||||
|
str[x] = '\0';
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_string_dowrap(void *ptr) {
|
||||||
|
// `ptr` is a pointer to a char*
|
||||||
|
char *str = *(char **)ptr;
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParsedValue *parse_dowrap(char *file, DArray *tokens, size_t *index) {
|
||||||
|
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
|
||||||
|
parsedValue->type = AST_DOWRAP;
|
||||||
|
DArray *dowrap_parsed = checked_malloc(sizeof(DArray));
|
||||||
|
darray_init(dowrap_parsed, sizeof(ParsedValue));
|
||||||
|
parsedValue->data = dowrap_parsed;
|
||||||
|
(*index)++;
|
||||||
|
if ((*index) >= tokens->size)
|
||||||
|
return parsedValue;
|
||||||
|
Token *token = darray_get(tokens, *index);
|
||||||
|
if (token->type != TOKEN_NEW_LINE) {
|
||||||
|
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line,
|
||||||
|
token->column);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
size_t indent_depth = 0;
|
||||||
|
bool temp_indent_depth_toggle = false;
|
||||||
|
size_t temp_indent_depth = 0;
|
||||||
|
bool pass = false;
|
||||||
|
DArray dowrap_tokens;
|
||||||
|
darray_init(&dowrap_tokens, sizeof(Token));
|
||||||
|
DArray to_free;
|
||||||
|
darray_init(&to_free, sizeof(char *));
|
||||||
|
|
||||||
|
size_t starting_index = *index;
|
||||||
|
|
||||||
|
size_t temp_index_count = 0;
|
||||||
|
|
||||||
|
while (!pass && ++(*index) < tokens->size) {
|
||||||
|
token = darray_get(tokens, *index);
|
||||||
|
switch (token->type) {
|
||||||
|
case TOKEN_INDENT:
|
||||||
|
temp_indent_depth_toggle = true;
|
||||||
|
if (dowrap_tokens.size == 0) {
|
||||||
|
indent_depth = strlen(token->value);
|
||||||
|
temp_indent_depth = indent_depth;
|
||||||
|
} else {
|
||||||
|
temp_indent_depth = strlen(token->value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TOKEN_NEW_LINE:
|
||||||
|
temp_indent_depth = 0;
|
||||||
|
temp_indent_depth_toggle = true;
|
||||||
|
darray_push(&dowrap_tokens, token);
|
||||||
|
temp_index_count++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (temp_indent_depth < indent_depth && temp_indent_depth_toggle) {
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (temp_indent_depth >= indent_depth) {
|
||||||
|
size_t indent_amount = temp_indent_depth-indent_depth;
|
||||||
|
Token indent_token;
|
||||||
|
indent_token.line = token->line;
|
||||||
|
indent_token.column = token->column;
|
||||||
|
indent_token.type = TOKEN_INDENT;
|
||||||
|
indent_token.value = repeat_space(indent_amount);
|
||||||
|
darray_push(&dowrap_tokens, &indent_token);
|
||||||
|
darray_push(&to_free, &indent_token.value);
|
||||||
|
}
|
||||||
|
temp_indent_depth_toggle = false;
|
||||||
|
temp_indent_depth = 0;
|
||||||
|
temp_index_count=0;
|
||||||
|
darray_push(&dowrap_tokens, token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*index)-=temp_index_count;
|
||||||
|
for (size_t i = 0; i<temp_index_count;i++) {
|
||||||
|
darray_pop(&dowrap_tokens, NULL);
|
||||||
|
}
|
||||||
|
parser(file, dowrap_parsed, &dowrap_tokens, false);
|
||||||
|
|
||||||
|
darray_free(&dowrap_tokens, NULL);
|
||||||
|
|
||||||
|
darray_free(&to_free, free_string_dowrap);
|
||||||
|
|
||||||
|
return parsedValue;
|
||||||
|
}
|
||||||
12
src/parser/dowrap/dowrap.h
Normal file
12
src/parser/dowrap/dowrap.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef DOWRAP_H
|
||||||
|
#define DOWRAP_H
|
||||||
|
#include "../parser.h"
|
||||||
|
#include "../../lexer/token.h" // for Token
|
||||||
|
|
||||||
|
// Function declaration for parsing an identifier
|
||||||
|
ParsedValue *parse_dowrap(char *file, DArray *tokens,
|
||||||
|
size_t *index);
|
||||||
|
|
||||||
|
void free_dowrap(void *ptr);
|
||||||
|
|
||||||
|
#endif // DOWRAP_H
|
||||||
@@ -1,24 +1,25 @@
|
|||||||
#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 "assignable/access/access.h"
|
||||||
#include "assignable/assign/assign.h"
|
#include "assignable/assign/assign.h"
|
||||||
|
#include "assignable/call/call.h"
|
||||||
#include "assignable/identifier/identifier.h"
|
#include "assignable/identifier/identifier.h"
|
||||||
#include "declaration/declaration.h"
|
#include "declaration/declaration.h"
|
||||||
|
#include "dowrap/dowrap.h"
|
||||||
#include "if/if.h"
|
#include "if/if.h"
|
||||||
|
#include "literals/literals.h"
|
||||||
#include "number/number.h"
|
#include "number/number.h"
|
||||||
#include "string/string.h"
|
#include "string/string.h"
|
||||||
#include "literals/literals.h"
|
|
||||||
#include "assignable/call/call.h"
|
|
||||||
#include "assignable/access/access.h"
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
const char *ValueTypeNames[] = {"string", "assign", "identifier",
|
const char *ValueTypeNames[] = {
|
||||||
"number", "if statement", "access",
|
"string", "assign", "identifier", "number", "if statement", "access",
|
||||||
"call", "declaration", "null", "boolean"};
|
"call", "declaration", "null", "boolean", "do wrap"};
|
||||||
|
|
||||||
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) {
|
||||||
@@ -78,11 +79,14 @@ ParsedValue *parse_token(char *file, DArray *tokens, size_t *index,
|
|||||||
case TOKEN_NEW_LINE:
|
case TOKEN_NEW_LINE:
|
||||||
(*index)++;
|
(*index)++;
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
|
||||||
case TOKEN_INDENT:
|
case TOKEN_INDENT:
|
||||||
fprintf(stderr, "%s:%zu:%zu error: invalid indentation\n", file, token->line,
|
if (strlen(token->value) > 0) {
|
||||||
token->column);
|
fprintf(stderr, "%s:%zu:%zu error: invalid indentation\n", file,
|
||||||
|
token->line, token->column);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
(*index)++;
|
||||||
|
return NULL;
|
||||||
case TOKEN_IDENTIFIER:
|
case TOKEN_IDENTIFIER:
|
||||||
(*index)++;
|
(*index)++;
|
||||||
output = parse_identifier(token);
|
output = parse_identifier(token);
|
||||||
@@ -94,6 +98,9 @@ ParsedValue *parse_token(char *file, DArray *tokens, size_t *index,
|
|||||||
case TOKEN_LET:
|
case TOKEN_LET:
|
||||||
output = parse_declaration(file, tokens, index);
|
output = parse_declaration(file, tokens, index);
|
||||||
break;
|
break;
|
||||||
|
case TOKEN_DO:
|
||||||
|
output = parse_dowrap(file, tokens, index);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line,
|
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line,
|
||||||
token->column);
|
token->column);
|
||||||
@@ -131,11 +138,21 @@ ParsedValue *parse_token(char *file, DArray *tokens, size_t *index,
|
|||||||
|
|
||||||
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;
|
||||||
|
bool expecting_new_line = false;
|
||||||
while (index < tokens->size) {
|
while (index < tokens->size) {
|
||||||
ParsedValue *parsed_code = parse_token(file, tokens, &index, inline_flag);
|
ParsedValue *parsed_code = parse_token(file, tokens, &index, inline_flag);
|
||||||
if (parsed_code) {
|
if (parsed_code) {
|
||||||
|
if (expecting_new_line) {
|
||||||
|
Token *token = darray_get(tokens, index-1);
|
||||||
|
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line,
|
||||||
|
token->column);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
expecting_new_line = true;
|
||||||
darray_push(parsed, parsed_code);
|
darray_push(parsed, parsed_code);
|
||||||
free(parsed_code);
|
free(parsed_code);
|
||||||
|
} else {
|
||||||
|
expecting_new_line = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ typedef enum {
|
|||||||
AST_CALL,
|
AST_CALL,
|
||||||
AST_DECLARATION,
|
AST_DECLARATION,
|
||||||
AST_NULL,
|
AST_NULL,
|
||||||
AST_BOOLEAN
|
AST_BOOLEAN,
|
||||||
|
AST_DOWRAP
|
||||||
} ValueType;
|
} ValueType;
|
||||||
|
|
||||||
extern const char* ValueTypeNames[];
|
extern const char* ValueTypeNames[];
|
||||||
|
|||||||
27
test.ar
27
test.ar
@@ -1,21 +1,6 @@
|
|||||||
let a,
|
x = do
|
||||||
b = 1,
|
do
|
||||||
c,
|
test
|
||||||
d = 42,
|
test
|
||||||
temp_result,
|
|
||||||
compute_area(radius) = 3.1415,
|
term.log("hello world")
|
||||||
identity(x) = x,
|
|
||||||
f(x),
|
|
||||||
g(y, z),
|
|
||||||
result,
|
|
||||||
z = 0,
|
|
||||||
extremely_long_variable_name_to_test_limits,
|
|
||||||
cache_value = compute_area(5),
|
|
||||||
placeholder_fn_with_no_body(arg1, arg2, arg3),
|
|
||||||
total = identity(100),
|
|
||||||
deeply_nested_args_function(arg1, arg2, arg3, arg4, arg5),
|
|
||||||
sum = a,
|
|
||||||
another,
|
|
||||||
another_function(),
|
|
||||||
just_null_here
|
|
||||||
if (x) term.log("hello world")
|
|
||||||
Reference in New Issue
Block a user