This commit is contained in:
Timerix22 2022-03-24 15:24:46 +03:00
parent e33e5eb751
commit 042e3e6670
9 changed files with 306 additions and 26 deletions

View File

@ -1 +1 @@
## Cobek ## cobek

13
cobek_compiler.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include "tokens.h"
#include "context.h"
Autoarr_declare(Token);
Autoarr(Token)* lexan(char* source, char* filename);
Context* parse(Autoarr(Token)* tokens);
string genBytecode(Context* toplvl_context);
Assembly genAssembly(Autoarr(string)* compiled_contexts, AssemblyParams params);

4
commands.c Normal file
View File

@ -0,0 +1,4 @@
#pragma once
#include "comands.h"
Autoarr_define(Command);

16
commands.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include "../kerep/Autoarr/Autoarr.h"
typedef enum CommandId{
} __attribute__((__packed__)) CommandId;
struct CommandStruct;
typedef CommandStruct Command;
struct CommandStruct{
Command* next;
Command* prev;
CommandId id;
}
Autoarr_declare(Comand);

3
context.c Normal file
View File

@ -0,0 +1,3 @@
#include "context.h"
Autoarr_define(Context);

14
context.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "commands.h"
struct ContextStruct;
typedef ContextStruct Context;
Autoarr_declare(Context);
struct ContextStruct{
Context* parent;
Autoarr(Context) children;
Autoarr(Command) commandChain;
Autoarr(Constant) constantStack;
}

227
lexer.c
View File

@ -1,24 +1,80 @@
#include "cobek_compiler.h"
Autoarr(Token)* lexan(char* source){ Autoarr_define(Token);
char charFromEscapeStr(string estr){
if(*estr.ptr!='\\') throw("first char is not \\");
switch(*(++estr.ptr)){
case 'n': return '\n';
case 'r': return '\r';
case 't': return '\t';
case 'e': return '\e';
case '\\': return '\\';
case '"': return '"';
case '\'': return '\'';
default: throw(ERR_WRONGCHAR);
}
}
Autoarr(Token)* lexan(char* source, char* filename){
Autoarr(Token)* tokens=malloc(sizeof(Autoarr(Token))); Autoarr(Token)* tokens=malloc(sizeof(Autoarr(Token)));
*tokens=Autoarr_create(Token,64,1024); *tokens=Autoarr_create(Token,64,1024);
char c; char c;
string label={source,0}; string label={source,0};
string line={source,0};
uint32 linenum;
uint32 cnum;
void throw_wrongchar(){
char* errline=string_cpToCharPtr(line);
printf("\n\e[91mwrong char <%c> at [%s:%u:%u %s]\n >>> %s\n" ,filename,linenum,cnum,c,errline);
exit(96);
};
void addlabel(){ void addlabel(){
if(label.length!=0) return; if(label.length==0) return;
Unitype token=ST_pull_str(label); Unitype token_ptr_u=ST_pull_str(label);
if(token.type==Null){ // user-defined label
//custom token if(token_ptr_u.type==Null){
Token ut={
.id=tok_label,
.value=string_cpToCharPtr(label)
};
switch(*label.ptr){
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
ut.id=tok_number;
break;
default:
break;
} }
Autoarr_add(tokens, (*token.VoidPtr)); Autoarr_add(tokens, ut);
}
// built-in keyword
else Autoarr_add(tokens, (*token_ptr_u.VoidPtr));
label={source,0}; label={source,0};
}; };
addtok(TokenId id){ addtok(TokenId id){
Autoarr_add(tokens, default_tokens[id]); Autoarr_add(tokens, default_tokens[id]);
} }
addtok_ifnext(char next, TokenId yes, TokenId no){
if(*(source+1)==next){
addtok(yes);
source++;
}
else addtok(no);
}
while ((c=*source++)) switch(c){ while ((c=*source++)) switch(c){
case ' ': case '\t': case ' ': case '\t':
case '\r': case '\n': case '\r': case '\n':
@ -28,7 +84,166 @@ Autoarr(Token)* lexan(char* source){
addlabel(); addlabel();
addtok(tok_lbracket); addtok(tok_lbracket);
break; break;
case '{':
addlabel();
addtok(tok_lbracket_fi);
break;
case '[':
addlabel();
addtok(tok_lbracket_sq);
break;
case ')':
addlabel();
addtok(tok_rbracket);
break;
case '}':
addlabel();
addtok(tok_rbracket_fi);
break;
case ']':
addlabel();
addtok(tok_rbracket_sq);
break;
case '\'':
addlabel();
Token ctok={
.id=tok_char ,
.value={++source,1}
};
if(*source=='\\'){
ctok.value=malloc(1);
*ctok.value=charFromEscapeStr(source++,2);
}
if(*(++source)!='\'')
throw_wrongchar();
Autoarr_add(tokens, ctok);
break;
case '"':
addlabel();
break;
case '<':
addlabel();
addtok(tok_less);
break;
case '>':
addlabel();
addtok(tok_more);
break;
case '+':
addlabel();
addtok(tok_plus);
break;
case '-':
addlabel();
addtok(tok_minus);
break;
case '*':
addlabel();
addtok(tok_asterisk);
break;
case '/':
addlabel();
if(*(++source)=='/'){
label={++source,0};
while((c=*(source++))
if(c=='\n'){
// removes \r from the end of comment line
if(*(source-2)=='\r')
label.length--;
goto add_comment;
} }
else label.length++;
add_comment:
Token comt={
.id=tok_comment,
.value=label
}
Autoarr_add(tokens,comt);
}
else if(*source=='*'){
label={++source,0};
while((c=*(source++))
if(c=='*'&&*(source++)=='/')
goto add_comment;
else label.length++;
add_comment:
Token comt={
.id=tok_comment,
.value=label
}
Autoarr_add(tokens,comt);
}
else{
source--;
addtok(tok_slash);
}
break;
case '=':
addlabel();
addtok_ifnext('=',tok_equals,tok_assign);
break;
case '!':
addlabel();
addtok_ifnext('=',tok_not_equals,tok_not);
break;
case '&':
addlabel();
addtok_ifnext('&',tok_,tok_);
break;
case '|':
addlabel();
addtok_ifnext('|',tok_or,tok_or_d);
break;
case '?':
addlabel();
addtok_ifnext('?',tok_question,tok_question_d);
break;
case ':':
addlabel();
addtok(tok_colon);
break;
case ';':
addlabel();
addtok(tok_semicolon);
break;
case '.':
addlabel();
addtok(tok_point);
break;
case ',':
addlabel();
addtok(tok_comma);
break;
case '~':
addlabel();
addtok(tok_tilda);
break;
case '\\':
addlabel();
addtok(tok_backslash);
break;
case '%':
addlabel();
addtok(tok_percent);
break;
case '^':
addlabel();
addtok(tok_xor);
break;
case '$':
addlabel();
addtok(tok_dollar);
break;
case '@':
addlabel();
addtok(tok_at);
break;
default:
label.length++;
break;
}
return tokens;
} }

5
parser.c Normal file
View File

@ -0,0 +1,5 @@
#include "cobek_compiler.h"
Context parse(Autoarr(Token)* tokens){
}

View File

@ -1,4 +1,5 @@
#include "" #pragma once
#include "../kerep/base/std.h"
typedef enum TokenId{ typedef enum TokenId{
// base types // base types
@ -23,63 +24,72 @@ typedef enum TokenId{
tok_false, tok_false,
// control flow operators // control flow operators
tok_if, tok_if,
tok_else,
tok_for, tok_for,
tok_while, tok_while,
tok_switch, tok_switch,
tok_case, tok_case,
tok_brake, tok_brake,
tok_braketo,
tok_return, tok_return,
tok_goto,
// declaration keywords // declaration keywords
tok_struct, tok_struct,
tok_enum, tok_enum,
tok_union, tok_union,
tok_alias,
tok_event, tok_event,
tok_import, tok_import,
// access modiiers tok_alias,
// access modifiers
tok_const, tok_const,
tok_protected, tok_protected,
tok_public, tok_public,
tok_virtual, tok_virtual,
// cpecial characters // user-defined
tok_label,
tok_number,
tok_char,
tok_string,
tok_comment,
// special characters
tok_lbracket, // ( tok_lbracket, // (
tok_lbracket_fi, // { tok_lbracket_fi, // {
tok_lbracket_sq, // [ tok_lbracket_sq, // [
tok_rbracket, // ) tok_rbracket, // )
tok_rbracket_fi, // } tok_rbracket_fi, // }
tok_rbracket_sq, // ] tok_rbracket_sq, // ]
tok_quot, // ' //tok_quot, // '
tok_quot_d, // " //tok_quot_d, // "
tok_less, // < tok_less, // <
tok_more, // > tok_more, // >
tok_plus, // + tok_plus, // +
tok_minus, // - tok_minus, // -
tok_multip, // * tok_asterisk, // *
tok_divide, // / tok_slash, // /
tok_assign, // = tok_assign, // =
tok_colon, // : tok_not, // !
tok_semicolon, // ; tok_equals, // ==
tok_point, // . tok_not_equals, // !=
tok_comma, // ,
tok_question, // ?
tok_question_d, // ??
tok_and, // & tok_and, // &
tok_and_d, // && tok_and_d, // &&
tok_or, // | tok_or, // |
tok_or_d, // || tok_or_d, // ||
tok_not, // ! tok_question, // ?
tok_equals, // == tok_question_d, // ??
tok_not_equals, // != tok_colon, // :
tok_semicolon, // ;
tok_point, // .
tok_comma, // ,
tok_tilda, // ~ tok_tilda, // ~
tok_backslash, // \ tok_backslash, // \
tok_percent, // % tok_percent, // %
tok_xor, // ^ tok_xor, // ^
tok_lattice, // # tok_lattice, // #
tok_dollar, // $ tok_dollar, // $
tok_ tok_at // @
} __attribute__((__packed__)) TokenId; } __attribute__((__packed__)) TokenId;
typedef struct Token{ typedef struct Token{
char* value;
TokenId id; TokenId id;
Unitype value;
} Token; } Token;