Skip to content

Commit

Permalink
🎨 use gwion as config lang
Browse files Browse the repository at this point in the history
  • Loading branch information
fennecdjay committed May 6, 2024
1 parent d8359eb commit 90444cf
Show file tree
Hide file tree
Showing 6 changed files with 851 additions and 37 deletions.
22 changes: 22 additions & 0 deletions include/casing.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <stdbool.h>
#include <string.h>

typedef bool (*casing_check_f)(const char *);
typedef bool (*casing_fix_f)(const char *s, char *, size_t);

typedef struct Casing {
casing_check_f check;
casing_fix_f fix;
const char *name;
} Casing;

typedef enum CasingType {
CAMELCASE,
PASCALCASE,
UPPERCASE,
SNAKECASE
} CasingType;

const Casing *get_casing(const CasingType);
9 changes: 7 additions & 2 deletions include/gwfmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,21 @@ typedef enum FmtColor {

#define MAX_COLOR_LENGTH 8

// TODO: use that!!!!!
typedef struct GwFmtMark {
uint16_t line;
char sign[16];
} GwFmtMark;

typedef struct Config {
Casing cases[LastCase];
char colors[LastColor][MAX_COLOR_LENGTH];
} Config;

typedef struct GwfmtState {
GwText text;
PPArg *ppa;
Casing cases[LastCase];
char colors[LastColor][MAX_COLOR_LENGTH];
Config *config;
unsigned int nindent;
MP_Vector *marks; // NOTE: make it a vector?
unsigned int base_column;
Expand Down
156 changes: 156 additions & 0 deletions src/casing.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#include "ctype.h"
#include "casing.h"

bool is_camel_case(const char *s) {
if(strchr(s, '_'))
return false;
if(isupper(*s))
return false;
return true;
}

bool is_pascal_case(const char *s) {
if(strchr(s, '_'))
return false;
if(islower(*s))
return false;
return true;
}

bool is_upper_case(const char *s) {
for(size_t i = 0; i < strlen(s); i++) {
if(!isupper(s[i]) && s[i] != '_' && !isdigit(s[i]))
return false;
}
return true;
}

bool is_snake_case(const char *s) {
for(size_t i = 0; i < strlen(s); i++) {
if(isupper(s[i]) && s[i] != '_' && !isdigit(s[i]))
return false;
}
return true;
}


#define SET(buf, j, value, len) \
do { \
if(j++ >= len) return false; \
buf[j -1] = value; \
} while(0)

bool fix_camel_case(const char *s, char *buf, size_t len) {
bool needsCap = false;
size_t j = 0;
SET(buf, j, tolower(s[0]), len);
for(size_t i = j; i < strlen(s); i++) {
if(s[i] == '_') {
needsCap = true;
continue;
} else {
if(needsCap) {
SET(buf, j, toupper(s[i]), len);
needsCap = false;
continue;
}
SET(buf, j, s[i], len);
}
}
SET(buf, j, '\0', len);
return true;
}

bool fix_pascal_case(const char *s, char *buf, size_t len) {
bool needsCap = true;
size_t j = 0;
for(size_t i = 0; i < strlen(s); i++) {
if(s[i] == '_') {
needsCap = true;
continue;
} else {
if(needsCap) {
SET(buf, j, toupper(s[i]), len);
needsCap = false;
continue;
}
SET(buf, j, s[i], len);
}
}
SET(buf, j, '\0', len);
return true;
}

bool fix_upper_case(const char *s, char *buf, size_t len) {
bool had_lower = false;
size_t j = 0;
for(size_t i = 0; i < strlen(s); i++) {
if(!isupper(s[i]) && s[i] != '_' && !isdigit(s[i])) {
SET(buf, j, toupper(s[i]), len);
had_lower = true;
} else {
if(had_lower){
SET(buf, j, '_', len);
had_lower = false;
}
SET(buf, j, s[i], len);
}
}
SET(buf, j, '\0', len);
return true;
}

bool fix_snake_case(const char *s, char *buf, size_t len) {
bool had_lower = true;
size_t j = 0;
for(size_t i = 0; i < strlen(s); i++) {
if(isupper(s[i])) {
if(had_lower && j) {
SET(buf, j, '_', len);
}
had_lower = false;
SET(buf, j, tolower(s[i]), len);
} else {
SET(buf, j, s[i], len);
had_lower = true;
}
}
SET(buf, j, '\0', len);
return true;
}


static const Casing camelCase = {
.check = is_camel_case,
.fix = fix_camel_case,
.name = "camelCase"
};

static const Casing PascalCase = {
.check = is_pascal_case,
.fix = fix_pascal_case,
.name = "PascalCase"
};

static const Casing UPPER_CASE = {
.check = is_upper_case,
.fix = fix_upper_case,
.name = "UPPER_CASE"
};

static const Casing snake_case = {
.check = is_snake_case,
.fix = fix_snake_case,
.name = "snake_case"
};

static const Casing *casings[4] = {
&camelCase,
&PascalCase,
&UPPER_CASE,
&snake_case
};

const Casing *get_casing(const CasingType t) {
return casings[t];
}
152 changes: 152 additions & 0 deletions src/gwion_config.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#include "gwion_util.h"
#include "gwion_ast.h"
#include "gwion_env.h"
#include "vm.h"
#include "gwion.h"
#include "arg.h"
#include "operator.h"
#include "instr.h"
#include "object.h"
#include "import.h"
#include "gwi.h"
#include "compile.h"

#define runtime_bool_func(name, value) \
static MFUN(fmt_##name) { \
struct GwfmtState *ls = **(struct GwfmtState***)MEM(0); \
ls->value = *(bool*)MEM(SZ_INT); \
}
runtime_bool_func(pythonize, py);
runtime_bool_func(unpythonize, unpy);
runtime_bool_func(only_pythonize, onlypy);
runtime_bool_func(minimize, minimize);
runtime_bool_func(pretty, pretty);
runtime_bool_func(show_lines, show_line);
runtime_bool_func(header, header);
runtime_bool_func(use_tabs, use_tabs);
runtime_bool_func(fix, fix);

static MFUN(fmt_color) {
struct GwfmtState *ls = **(struct GwfmtState***)MEM(0);
ls->color = *(m_uint*)MEM(SZ_INT);
}

static MFUN(fmt_setcolor) {
struct GwfmtState *ls = **(struct GwfmtState***)MEM(0);
const FmtColor kind = (FmtColor)*(m_uint*)MEM(SZ_INT);
const M_Object color = *(M_Object*)MEM(SZ_INT*2);
set_color(ls, kind, STRING(color));
}


#define runtime_case_func(name, value) \
static MFUN(fmt_##name##_case) { \
struct GwfmtState *ls = **(struct GwfmtState***)MEM(0); \
ls->config->cases[value##Case] = *get_casing(*(CasingType*)MEM(SZ_INT)); \
}
runtime_case_func(type, Type);
runtime_case_func(function, Function);
runtime_case_func(variable, Variable);

GWION_IMPORT(GwFmt) {
GWI_B(gwi_enum_ini(gwi, "ColorKind"));
GWI_B(gwi_enum_add(gwi, "StringColor", StringColor));
GWI_B(gwi_enum_add(gwi, "KeywordColor", KeywordColor));
GWI_B(gwi_enum_add(gwi, "FlowColor", FlowColor));
GWI_B(gwi_enum_add(gwi, "FunctionColor", FunctionColor));
GWI_B(gwi_enum_add(gwi, "TypeColor", TypeColor));
GWI_B(gwi_enum_add(gwi, "VariableColor", VariableColor));
GWI_B(gwi_enum_add(gwi, "NumberColor", NumberColor));
GWI_B(gwi_enum_add(gwi, "OpColor", OpColor));
GWI_B(gwi_enum_add(gwi, "ModColor", ModColor));
GWI_B(gwi_enum_add(gwi, "PunctuationColor", PunctuationColor));
GWI_B(gwi_enum_add(gwi, "PPColor", PPColor));
GWI_B(gwi_enum_add(gwi, "SpecialColor", SpecialColor));
GWI_B(gwi_enum_end(gwi));

GWI_B(gwi_enum_ini(gwi, "ColorWhen"));
GWI_B(gwi_enum_add(gwi, "Always", COLOR_ALWAYS));
GWI_B(gwi_enum_add(gwi, "Auto", COLOR_AUTO));
GWI_B(gwi_enum_add(gwi, "Never", COLOR_NEVER));
GWI_B(gwi_enum_end(gwi));

GWI_B(gwi_enum_ini(gwi, "Case"));
GWI_B(gwi_enum_add(gwi, "PascalCase", PASCALCASE));
GWI_B(gwi_enum_add(gwi, "camelCase", CAMELCASE));
GWI_B(gwi_enum_add(gwi, "UPPER_CASE", UPPERCASE));
GWI_B(gwi_enum_add(gwi, "snake_case", SNAKECASE));
GWI_B(gwi_enum_end(gwi));

GWI_B(gwi_struct_ini(gwi, "GwFmt"));
gwi->gwion->env->class_def->size = SZ_INT;

#define import_bool_fun(name) \
GWI_B(gwi_func_ini(gwi, "void", #name)); \
GWI_B(gwi_func_arg(gwi, "bool", "arg")); \
GWI_B(gwi_func_end(gwi, fmt_##name, ae_flag_none)); \

import_bool_fun(pythonize);
import_bool_fun(unpythonize);
import_bool_fun(only_pythonize);
import_bool_fun(minimize);
import_bool_fun(pretty);
import_bool_fun(header);
import_bool_fun(show_lines);
import_bool_fun(use_tabs);
import_bool_fun(fix);

GWI_B(gwi_func_ini(gwi, "void", "color"));
GWI_B(gwi_func_arg(gwi, "ColorWhen", "arg"));
GWI_B(gwi_func_end(gwi, fmt_color, ae_flag_none));


GWI_B(gwi_func_ini(gwi, "void", "color"));
GWI_B(gwi_func_arg(gwi, "ColorKind", "arg"));
GWI_B(gwi_func_end(gwi, fmt_setcolor, ae_flag_none));


#define import_case_fun(name) \
GWI_B(gwi_func_ini(gwi, "void", #name "_case")); \
GWI_B(gwi_func_arg(gwi, "Case", "arg")); \
GWI_B(gwi_func_end(gwi, fmt_##name##_case, ae_flag_none));

import_case_fun(type);
import_case_fun(function);
import_case_fun(variable);

GWI_B(gwi_struct_end(gwi));

GWI_B(gwi_item_ini(gwi, "GwFmt", "gwfmt"));
GWI_B(gwi_item_end(gwi, ae_flag_const, obj, NULL));
return true;
}

static bool init_gwion(Gwion gwion) {
char *argv = (m_str)"gwfmt";
CliArg arg = {
.arg = { .argv = &argv, .argc = 1 },
.thread_count = 1,
.queue_size = 1,
};
const bool ret = gwion_ini(gwion, &arg);
arg_release(&arg);
return ret && gwi_run(gwion, gwimport_GwFmt);
}

static bool run(Gwion gwion, const char *filename) {
const bool ret = compile_filename(gwion, filename);
if(ret)
vm_force_run(gwion->vm);
return ret;
}

bool run_config(struct GwfmtState *ls, const char *filename) {
struct Gwion_ gwion;
if(!init_gwion(&gwion))
return false;
Value value = nspc_lookup_value1(gwion.env->curr, insert_symbol(gwion.st, "gwfmt"));
value->d.ptr = (m_uint*)ls;
const bool ret = run(&gwion, filename);
gwion_end(&gwion);
return ret;
}
Loading

0 comments on commit 90444cf

Please sign in to comment.