add dictionaries and add accessing with a value

This commit is contained in:
2025-06-12 04:37:07 +01:00
parent f8207702e1
commit b05408ebec
10 changed files with 190 additions and 38 deletions

View File

@@ -1,39 +1,42 @@
let __makeFile(name, type, data) = do let __makeFile(name, type, data) = do
let File = {name: name, type: type, data: data}
let save(path) = do let save(path) = do
let file = file.write(path) let file = file.write(path)
file.buffer(data) file.buffer(data)
file.close() file.close()
File.save = save File.save = save
return File
let __multipart(req, res) = do let __multipart(req, res) = do
let boundary = buffer().from(req.headers.splitN("boundary=", 2)) let boundary = buffer().from(req.headers["content-type"].splitN("boundary=", 2)[1])
let newLineSplit = buffer().from("\r\n\r\n") let newLineSplit = buffer().from("\r\n\r\n")
let parts = req.buffer.body.split(boundary) let parts = req.buffer.body.split(boundary)
if (true) do for (i from 0 to parts.length) do
let str = parts.to("string") let str = parts[i].to("string")
if (str == "" || str=="--" || str=="--\r\n") do if (str == "" || str=="--" || str=="--\r\n") continue
str = null str = null
let headers = [] let headers = {}
let lines = parts.splitN(newLineSplit, 2) let lines = parts[i].splitN(newLineSplit, 2)
let headerLines = lines.to("string").split("\r\n") let headerLines = lines[0].to("string").split("\r\n")
if (true) do for (j from 0 to headerLines.length) do
let header = headerLines.splitN(": ", 2) let header = headerLines[j].splitN(": ", 2)
if (header.length != 2) do if (header.length != 2) continue
headers = header headers[header[0].lower()] = header[1]
if (lines.length != 2) do if (lines.length != 2) continue
let body = lines let body = lines[1]
if (i != parts.length-1) do if (i != parts.length-1) do
body = body.slice(0, body.length-4) body = body.slice(0, body.length-4)
if ("content-disposition" in headers) do if ("content-disposition" in headers) do
let disposition = headers.split("; ") let disposition = headers["content-disposition"].split("; ")
if (disposition == "form-data") do if (disposition[0] == "form-data") do
let name = json.parse(disposition.splitN("=", 2)) let name = json.parse(disposition[1].splitN("=", 2)[1])
if (disposition.length >= 3) do if (disposition.length >= 3) do
let filename = json.parse(disposition.splitN("=", 2)) let filename = json.parse(disposition[2].splitN("=", 2)[1])
req.files = __makeFile(filename, headers, body) req.files[name] = __makeFile(filename, headers["content-type"], body)
else do else do
req.formdata = body.to("string") req.formdata[name] = body.to("string")
res.next() res.next()

View File

@@ -5,7 +5,6 @@
typedef enum { typedef enum {
TOKEN_STRING = 256, TOKEN_STRING = 256,
TOKEN_NUMBER, TOKEN_NUMBER,
TOKEN_FRACTION,
TOKEN_IDENTIFIER, TOKEN_IDENTIFIER,
TOKEN_KEYWORD, TOKEN_KEYWORD,
TOKEN_NEW_LINE, TOKEN_NEW_LINE,

View File

@@ -1,18 +1,48 @@
#include "access.h" #include "access.h"
#include "../../../lexer/token.h" #include "../../../lexer/token.h"
#include "../../parser.h"
#include <string.h>
#include <stdlib.h>
#include "../../../memory.h" #include "../../../memory.h"
#include "../../parser.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
ParsedValue *parse_access(char*file,DArray *tokens, size_t * index, ParsedValue * to_access) { ParsedValue *parse_access(char *file, DArray *tokens, size_t *index,
ParsedValue *to_access) {
Token *first_token = darray_get(tokens, *index);
(*index)++; (*index)++;
error_if_finished(file, tokens, index);
Token * token = darray_get(tokens, *index);
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
ParsedAccess *parsedAccess = checked_malloc(sizeof(ParsedAccess)); ParsedAccess *parsedAccess = checked_malloc(sizeof(ParsedAccess));
parsedAccess->to_access = to_access; parsedAccess->to_access = *to_access;
parsedAccess->access = strcpy(checked_malloc(strlen(token->value) + 1), token->value); free(to_access);
darray_init(&parsedAccess->access, sizeof(ParsedValue));
if (first_token->type == TOKEN_DOT) {
error_if_finished(file, tokens, index);
Token *token = darray_get(tokens, *index);
ParsedValue parsedString;
parsedString.type = AST_STRING;
parsedString.data =
strcpy(checked_malloc(strlen(token->value) + 1), token->value);
darray_push(&parsedAccess->access, &parsedString);
} else {
while (true) {
skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index);
ParsedValue *parsedValue = parse_token(file, tokens, index, true);
darray_push(&parsedAccess->access, parsedValue);
free(parsedValue);
skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index);
Token *token = darray_get(tokens, *index);
if (token->type == TOKEN_RBRACKET) {
break;
} else if (token->type != TOKEN_COLON) {
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file,
token->line, token->column);
exit(EXIT_FAILURE);
}
(*index)++;
}
}
parsedValue->type = AST_ACCESS; parsedValue->type = AST_ACCESS;
parsedValue->data = parsedAccess; parsedValue->data = parsedAccess;
(*index)++; (*index)++;
@@ -22,8 +52,7 @@ ParsedValue *parse_access(char*file,DArray *tokens, size_t * index, ParsedValue
void free_parse_access(void *ptr) { void free_parse_access(void *ptr) {
ParsedValue *parsedValue = ptr; ParsedValue *parsedValue = ptr;
ParsedAccess *parsedAccess = parsedValue->data; ParsedAccess *parsedAccess = parsedValue->data;
free_parsed(parsedAccess->to_access); free_parsed(&parsedAccess->to_access);
free(parsedAccess->access); darray_free(&parsedAccess->access, free_parsed);
free(parsedAccess->to_access);
free(parsedAccess); free(parsedAccess);
} }

View File

@@ -4,8 +4,8 @@
#include "../../../lexer/token.h" // for Token #include "../../../lexer/token.h" // for Token
typedef struct { typedef struct {
ParsedValue * to_access; ParsedValue to_access;
char * access; DArray access;
} ParsedAccess; } ParsedAccess;
// Function declaration for parsing an identifier // Function declaration for parsing an identifier

View File

@@ -0,0 +1,88 @@
#include "dictionary.h"
#include "../../lexer/token.h"
#include "../../memory.h"
#include "../parser.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
ParsedValue *parse_dictionary(char *file, DArray *tokens, size_t *index) {
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
parsedValue->type = AST_DICTIONARY;
DArray *dictionary = checked_malloc(sizeof(DArray));
parsedValue->data = dictionary;
darray_init(dictionary, sizeof(ParsedValue));
(*index)++;
skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index);
Token *token = darray_get(tokens, *index);
if (token->type != TOKEN_RBRACE) {
while (true) {
skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index);
size_t keyIndex = *index;
Token *keyToken = darray_get(tokens, *index);
ParsedValue *key = parse_token(file, tokens, index, true);
if (keyToken->type == TOKEN_IDENTIFIER) {
key->type = AST_STRING;
}
skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index);
token = darray_get(tokens, *index);
ParsedValue *value;
bool tobreak = false;
switch (token->type) {
case TOKEN_COLON:
(*index)++;
skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index);
value = parse_token(file, tokens, index, true);
skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index);
token = darray_get(tokens, *index);
if (token->type == TOKEN_RBRACE) {
tobreak = true;
} else if (token->type != TOKEN_COMMA) {
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line,
token->column);
exit(EXIT_FAILURE);
}
break;
case TOKEN_RBRACE:
tobreak = true;
/* fall through */
case TOKEN_COMMA:
value = parse_token(file, tokens, &keyIndex, true);
break;
default:
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line,
token->column);
exit(EXIT_FAILURE);
}
ParsedDictionaryEntry entry = {key, value};
darray_push(dictionary, &entry);
if (tobreak) {
break;
}
(*index)++;
error_if_finished(file, tokens, index);
}
}
(*index)++;
return parsedValue;
}
void free_dictionary_entry(void *ptr) {
ParsedDictionaryEntry *entry = ptr;
free_parsed(entry->key);
free(entry->key);
free_parsed(entry->value);
free(entry->value);
}
void free_parsed_dictionary(void *ptr) {
ParsedValue *parsedValue = ptr;
DArray *parsed_dictionary = parsedValue->data;
darray_free(parsed_dictionary, free_dictionary_entry);
free(parsedValue->data);
}

View File

@@ -0,0 +1,16 @@
#ifndef DICTIONARY_H
#define DICTIONARY_H
#include "../../lexer/token.h" // for Token
#include "../parser.h"
typedef struct {
ParsedValue * key;
ParsedValue * value;
} ParsedDictionaryEntry;
ParsedValue *parse_dictionary(char *file, DArray *tokens,
size_t *index);
void free_parsed_dictionary(void *ptr);
#endif // DICTIONARY_H

View File

@@ -1,3 +1,4 @@
#include "list.h"
#include "../../lexer/token.h" #include "../../lexer/token.h"
#include "../../memory.h" #include "../../memory.h"
#include "../parser.h" #include "../parser.h"
@@ -12,6 +13,7 @@ ParsedValue *parse_list(char *file, DArray *tokens, size_t *index) {
parsedValue->data = list; parsedValue->data = list;
darray_init(list, sizeof(ParsedValue)); darray_init(list, sizeof(ParsedValue));
(*index)++; (*index)++;
skip_newlines_and_indents(tokens, 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_RBRACKET) { if (token->type != TOKEN_RBRACKET) {

View File

@@ -6,6 +6,7 @@
#include "assignable/call/call.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 "dictionary/dictionary.h"
#include "dowrap/dowrap.h" #include "dowrap/dowrap.h"
#include "if/if.h" #include "if/if.h"
#include "list/list.h" #include "list/list.h"
@@ -21,9 +22,9 @@
#include <string.h> #include <string.h>
const char *ValueTypeNames[] = { const char *ValueTypeNames[] = {
"string", "assign", "identifier", "number", "if statement", "string", "assign", "identifier", "number", "if statement",
"access", "call", "declaration", "null", "boolean", "access", "call", "declaration", "null", "boolean",
"do wrap", "operations", "list"}; "do wrap", "operations", "list", "dictionary"};
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) {
@@ -114,6 +115,9 @@ ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index,
case TOKEN_LBRACKET: case TOKEN_LBRACKET:
output = parse_list(file, tokens, index); output = parse_list(file, tokens, index);
break; break;
case TOKEN_LBRACE:
output = parse_dictionary(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);
@@ -139,6 +143,7 @@ ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index,
output = parse_call(file, tokens, index, output); output = parse_call(file, tokens, index, output);
break; break;
case TOKEN_DOT: case TOKEN_DOT:
case TOKEN_LBRACKET:
output = parse_access(file, tokens, index, output); output = parse_access(file, tokens, index, output);
break; break;
SWITCH_OPERATIONS SWITCH_OPERATIONS
@@ -183,6 +188,10 @@ void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) {
} }
void free_parsed(void *ptr) { void free_parsed(void *ptr) {
if (!ptr) {
fprintf(stderr, "panic: freeing NULL pointer\n");
exit(EXIT_FAILURE);
}
ParsedValue *parsed = ptr; ParsedValue *parsed = ptr;
switch (parsed->type) { switch (parsed->type) {
case AST_IDENTIFIER: case AST_IDENTIFIER:
@@ -219,5 +228,8 @@ void free_parsed(void *ptr) {
case AST_LIST: case AST_LIST:
free_parsed_list(parsed); free_parsed_list(parsed);
break; break;
case AST_DICTIONARY:
free_parsed_dictionary(parsed);
break;
} }
} }

View File

@@ -38,7 +38,8 @@ typedef enum {
AST_BOOLEAN, AST_BOOLEAN,
AST_DOWRAP, AST_DOWRAP,
AST_OPERATION, AST_OPERATION,
AST_LIST AST_LIST,
AST_DICTIONARY
} ValueType; } ValueType;
extern const char* ValueTypeNames[]; extern const char* ValueTypeNames[];

View File

@@ -48,3 +48,5 @@ x = [
'wow', 'wow',
10 10
] ]
term.log(x[0:1:1])