Skip to content

Commit

Permalink
fix func arg macro error
Browse files Browse the repository at this point in the history
  • Loading branch information
ysw421 committed Aug 31, 2024
1 parent 54de569 commit 57d48f6
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 83 deletions.
1 change: 0 additions & 1 deletion src/lib/init.or
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ satisfy R :: R = "real number"

% Macro
\newcommand{\pi}[0]{3.14159265}
\newcommand{\aa}[1]{#1}
\newcommand{\sum}[1]{
\begin{code}
...result := 0
Expand Down
70 changes: 70 additions & 0 deletions src/parser/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,76 @@ AST* parser_get_compound(Parser* parser, GET_COMPOUND_ENV* compound_env)
);
token = parser->token;
}
else if (value_node->value.value_v->size == 1
&& value_node->value.value_v->stack->type == AST_VALUE_MACRO
&& value_node->value.value_v->stack->value.macro_v->args_size == 0
&& parser
&& parser->prev_token
&& parser->token
&& parser->token->type == TOKEN_DEFINE
&& parser->prev_token->col == parser->token->col_first)
{
parser = parser_advance(parser, TOKEN_DEFINE);
token = parser->token;

if (!token)
{
orora_error("에러, ':=' 사용에 목적이 없음.", parser);
}

if (parser->prev_token->col != token->col_first)
{
orora_error("에러, ':=' 뒤에는 값이 와야함.", parser);
}

AST* macro_value_node =
parser_get_value(
&parser,
ast,
token,
init_get_value_env(),
compound_env
);
token = parser->prev_token;

if (!macro_value_node)
{
orora_error("에러, ':=' 뒤에는 값이 와야함...", parser);
}

AST* args_ast = init_ast(AST_COMPOUND, ast, token);
args_ast->value.compound_v = init_ast_compound();
args_ast->value.compound_v->size = 1;
args_ast->value.compound_v->items = malloc(sizeof(AST*));
args_ast->value.compound_v->items[0] = init_ast(AST_VALUE, ast, token);
args_ast->value.compound_v->items[0]->value.value_v = init_ast_value();
args_ast->value.compound_v->items[0]->value.value_v->size = 1;
args_ast->value.compound_v->items[0]->value.value_v->stack = init_ast_value_stack(AST_VALUE_INT, token);
args_ast->value.compound_v->items[0]->value.value_v->stack->value.int_v = malloc(sizeof(struct ast_int_t));
args_ast->value.compound_v->items[0]->value.value_v->stack->value.int_v->value = 0;

AST* code_ast = init_ast(AST_COMPOUND, ast, token);
code_ast->value.compound_v = init_ast_compound();
code_ast->value.compound_v->size = 1;
code_ast->value.compound_v->items = malloc(sizeof(AST*));
code_ast->value.compound_v->items[0] = macro_value_node;

AST* name_ast = init_ast(AST_COMPOUND, ast, token);
name_ast->value.compound_v = init_ast_compound();
name_ast->value.compound_v->size = 1;
name_ast->value.compound_v->items = malloc(sizeof(AST*));
name_ast->value.compound_v->items[0] = value_node;

AST* new_ast_node =
init_ast(AST_NEWENV, ast, token);
new_ast_node->value.newenv_v = init_ast_newenv();
new_ast_node->value.newenv_v->name = name_ast;
new_ast_node->value.newenv_v->args_size = args_ast;
new_ast_node->value.newenv_v->code = code_ast;

ast_compound_add(ast->value.compound_v, new_ast_node);
token = parser->token;
}
else
{
free(stoken);
Expand Down
16 changes: 16 additions & 0 deletions src/parser/parser_id.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,22 @@ AST* parser_parse_function(Parser* parser, AST* ast, Token* last_token,
check_arg_num * sizeof(char*));
s_arg_variaable_name[check_arg_num - 1] = variable_name;
}
else if (fa->args[i]->type == AST_VALUE
&& fa->args[i]->value.value_v->stack->type == AST_VALUE_MACRO)
{
char* macro_name =
fa->args[i]->value.value_v->stack->value.macro_v->name;
for (int j = 0; j < check_arg_num; j ++)
{
if (!strcmp(s_arg_variaable_name[j], macro_name))
{
const char* error_message = "에러, 함수 ";
error_message = const_strcat(error_message, fa->name);
error_message = const_strcat(error_message, "의 argument 이름이 중복됨");
orora_error(error_message, parser);
}
}
}
else
{
const char* error_message = "에러, 함수 ";
Expand Down
218 changes: 136 additions & 82 deletions src/visitor/visitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,12 @@ AST_value_stack* visitor_get_value_from_macro
code_ast->value.compound_v->size = 1;
code_ast->value.compound_v->items[0] = ast_macro->args[i];

if (ast_macro->args[i]->type == AST_VARIABLE && ast_macro->args[i]->value.variable_v->ast_type == AST_VARIABLE_DEFINE)
{
Env_variable* env_variable = visitor_variable_define(new_envs, ast_macro->args[i]->value.variable_v);

}

AST_newenv* newenv = init_ast_newenv();
newenv->name = name_ast;
newenv->args_size = args_size_ast;
Expand Down Expand Up @@ -1926,112 +1932,160 @@ Envs* visitor_get_envs_from_function
}

Env_variable** args = malloc(sizeof(Env_variable*) * env_function->args_size);
Env_macro** macros = malloc(sizeof(Env_macro*) * env_function->args_size);
bool is_variable[env_function->args_size];

int args_cnt = 0;
int macros_cnt = 0;

for (int i = 0; i < env_function->args_size; i ++)
{
AST_variable* ast_variable =
env_function->args[i]->value.variable_v;
if (i < ast_function->args_size)
if (env_function->args[i]->type == AST_VARIABLE)
{
AST* ast = ast_function->args[i];
Env_variable* env_variable =
init_env_variable(ast_variable->name,
ast_variable->name_length);

if (ast->type == AST_VARIABLE)
is_variable[i] = true;
AST_variable* ast_variable =
env_function->args[i]->value.variable_v;
if (i < ast_function->args_size)
{
switch (ast->value.variable_v->ast_type)
{
case AST_VARIABLE_VALUE:
Env_variable* value_variable =
visitor_get_variable(new_envs,
ast->value.variable_v);
if (!value_variable)
{
visitor_nondefine_variable_error(
ast->value.variable_v);
}

env_variable->type = value_variable->type;
env_variable->value = value_variable->value;
break;

case AST_VARIABLE_DEFINE:
value_variable =
visitor_variable_define(new_envs,
ast->value.variable_v);
env_variable->type = value_variable->type;
env_variable->value = value_variable->value;
break;
AST* ast = ast_function->args[i];
Env_variable* env_variable =
init_env_variable(ast_variable->name,
ast_variable->name_length);

default:
orora_error("에러, 해당 에러는 발생 불가함", (void*) 0);
// printf("에러, 해당 에러는 발생 불가함\n");
// exit(1);
if (ast->type == AST_VARIABLE)
{
switch (ast->value.variable_v->ast_type)
{
case AST_VARIABLE_VALUE:
Env_variable* value_variable =
visitor_get_variable(new_envs,
ast->value.variable_v);
if (!value_variable)
{
visitor_nondefine_variable_error(
ast->value.variable_v);
}

env_variable->type = value_variable->type;
env_variable->value = value_variable->value;
break;

case AST_VARIABLE_DEFINE:
value_variable =
visitor_variable_define(new_envs,
ast->value.variable_v);
env_variable->type = value_variable->type;
env_variable->value = value_variable->value;
break;

default:
orora_error("에러, 해당 에러는 발생 불가함", (void*) 0);
// printf("에러, 해당 에러는 발생 불가함\n");
// exit(1);
}
}
else
{
AST_value_stack* new_value =
visitor_get_value_from_ast(new_envs, ast);
orora_value_type* variable_type =
get_single_value_type(new_value->type);
env_variable =
variable_type
->visitor_set_value_Env_variable_from_AST_value_stack(
env_variable,
new_value
);
}

// Envs* global_envs = new_envs->global;
// Env_variable* global_variable =
// visitor_get_variable(global_envs, ast_variable);
// if (global_variable)
// {
// global_variable->type = env_variable->type;
// global_variable->value = env_variable->value;
// }
// else
// {
// global_variable = get_deep_copy_env_variable(env_variable);
// global_variable->next = global_envs->local->variables;
// global_envs->local->variable_size ++;
// global_envs->local->variables = global_variable;
// }

// Env* local_env = new_envs->local;
// env_variable->next = local_env->variables;
// local_env->variable_size ++;
// local_env->variables = env_variable;
args[args_cnt] = env_variable;
args_cnt ++;
}
else
{
AST_value_stack* new_value =
visitor_get_value_from_ast(new_envs, ast);
orora_value_type* variable_type =
get_single_value_type(new_value->type);
env_variable =
variable_type
->visitor_set_value_Env_variable_from_AST_value_stack(
env_variable,
new_value
);
if (env_function->args[i]
->value.variable_v->ast_type == AST_VARIABLE_DEFINE)
{
Env_variable* env_variable =
init_env_variable(ast_variable->name,
ast_variable->name_length);

env_variable = visitor_variable_define(new_envs, env_function->args[i]->value.variable_v);
args[args_cnt] = env_variable;
args_cnt ++;
}
else
{
orora_error("에러, 함수의 매개변수 개수가 다름", (void*) 0);
// printf("에러, 함수의 매개변수 개수가 다름\n");
// exit(1);
}
}

// Envs* global_envs = new_envs->global;
// Env_variable* global_variable =
// visitor_get_variable(global_envs, ast_variable);
// if (global_variable)
// {
// global_variable->type = env_variable->type;
// global_variable->value = env_variable->value;
// }
// else
// {
// global_variable = get_deep_copy_env_variable(env_variable);
// global_variable->next = global_envs->local->variables;
// global_envs->local->variable_size ++;
// global_envs->local->variables = global_variable;
// }

// Env* local_env = new_envs->local;
// env_variable->next = local_env->variables;
// local_env->variable_size ++;
// local_env->variables = env_variable;
args[i] = env_variable;
}
else
else if (env_function->args[i]->type == AST_VALUE
&& env_function->args[i]->value.value_v->stack->type == AST_VALUE_MACRO)
{
if (env_function->args[i]
->value.variable_v->ast_type == AST_VARIABLE_DEFINE)
is_variable[i] = false;
AST_macro* ast_macro = env_function->args[i]->value.value_v->stack->value.macro_v;
if (i < ast_function->args_size)
{
Env_variable* env_variable =
init_env_variable(ast_variable->name,
ast_variable->name_length);
AST* ast = ast_function->args[i];

Env_macro* env_macro =
init_env_macro(ast_macro->name, 0, ast);

env_variable = visitor_variable_define(new_envs, env_function->args[i]->value.variable_v);
args[i] = env_variable;
macros[macros_cnt] = env_macro;
macros_cnt ++;
}
else
{
orora_error("에러, 함수의 매개변수 개수가 다름", (void*) 0);
// printf("에러, 함수의 매개변수 개수가 다름\n");
// exit(1);
orora_error("에러, macro는 기본 값 설정이 불가함", (void*) 0);
}
}
else
{
orora_error("에러, 함수의 매개변수는 변수 또는 매크로만 가능함..", (void*) 0);
}
}
Env* local_env = new_envs->local;
int variable_cnt = 0;
int macro_cnt = 0;
for (int i = 0; i < env_function->args_size; i ++)
{
args[i]->next = local_env->variables;
local_env->variable_size ++;
local_env->variables = args[i];
if (is_variable[i])
{
args[variable_cnt]->next = local_env->variables;
local_env->variable_size ++;
local_env->variables = args[variable_cnt];
variable_cnt ++;
}
else
{
macros[macro_cnt]->next = local_env->macros;
local_env->macro_size ++;
local_env->macros = macros[macro_cnt];
macro_cnt ++;
}
}

return new_envs;
Expand Down

0 comments on commit 57d48f6

Please sign in to comment.