Skip to content

Commit

Permalink
working on match and case statement. the problem is nested match and …
Browse files Browse the repository at this point in the history
…case statement dont work as of now but will be fixed soon
  • Loading branch information
SaptakBhoumik committed Oct 4, 2021
1 parent 104ce55 commit 093a0d5
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 37 deletions.
23 changes: 23 additions & 0 deletions swallow/builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,26 @@ double mypow(double base, double power)
return 1 / result;
}
}
int compare(char *a,char *b) {
int flag=0;
if(a==NULL || b==NULL){
if (a==NULL && b==NULL){
flag=0;
}
else{
flag=1;
}
}
else{
while(*a!='\0' && *b!='\0') // while loop
{
if(*a!=*b)
{
flag=1;
}
a++;
b++;
}
}
return flag;
}
180 changes: 145 additions & 35 deletions swallow/codegen/codegen.v
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ module codegen
import parser

pub fn codegen(ast parser.Ast) []string {
loop := ['if', 'while', 'elif', 'else', 'for', 'match', 'case', 'default']
loop := ['if', 'while', 'elif', 'else', 'for', 'match', 'case']
if_else_loop := ['if', 'while', 'elif', 'else', 'for']
mut is_function_call := false
mut is_match_case:=false
mut is_default:=false
mut last_match:=[]parser.Body{}
mut match_item:=[]string{}
mut sign := ''
mut is_string_compare := false
mut function := parser.Function{}
Expand All @@ -26,8 +30,11 @@ pub fn codegen(ast parser.Ast) []string {
mut next_item := parser.Body{}
for index, mut item in ast.body {
keyword = item.keyword
if item.ast_type == 'new_line' {
item.keyword = ''
if item.keyword=="case" || item.keyword=="default" || item.keyword=="match"{
is_match_case=true
}
else if item.keyword=="else" && match_item.len>=1{
is_match_case=true
}
if index < ast.body.len - 1 && index != 0 {
next_item = ast.body[index + 1]
Expand All @@ -37,28 +44,7 @@ pub fn codegen(ast parser.Ast) []string {
} else if 'required' in previous_code_block.ast_type.split('_') && item.direction != 'right' {
code << '){\n'
}
if item.keyword == 'case' && is_case == false {
is_case = true
if is_match == true {
code << '){\n'
is_match = false
}
} else if item.keyword == 'match' && is_match == false {
is_match = true
if is_case == true {
code << '):{\n'
is_case = false
}
} else if is_case == true && item.direction == 'left' {
is_loop = false
code << '):{\n'
is_case = false
} else if item.keyword == 'default' {
// do nothing
} else if previous_code_block.keyword == 'default' {
is_loop = false
code << ':{\n'
} else if is_loop == true && (item.direction == 'left' || item.keyword == 'pass') {
if is_loop == true && (item.direction == 'left' || item.keyword == 'pass'){
if previous_code_block.keyword != 'else' {
if is_string_compare == true {
code << ')${sign}0'
Expand All @@ -70,6 +56,7 @@ pub fn codegen(ast parser.Ast) []string {
code << '{\n'
}
is_loop = false
is_case = false
} else if 'required' in previous_code_block.ast_type.split('_') && item.direction == 'right'
&& 'required' in item.ast_type.split('_') {
code << ','
Expand All @@ -88,18 +75,18 @@ pub fn codegen(ast parser.Ast) []string {
}
item.keyword = keyword
}
if previous_code_block.keyword in if_else_loop || previous_code_block.keyword == 'or'
|| previous_code_block.keyword == 'and' {
if (previous_code_block.keyword in if_else_loop || previous_code_block.keyword == 'or'
|| previous_code_block.keyword == 'and' ) && is_case==false{
if item.ast_type == 'string' {
code << ' strcmp('
code << ' compare('
is_string_compare = true
} else if item.ast_type == 'variable' && item.keyword in function.variable
&& var_type(function.variable_type, keyword) == 'str' {
code << ' strcmp('
code << ' compare('
is_string_compare = true
} else if item.ast_type == 'function_call'
&& func_return_if_else(keyword, ast) == ['str'] {
code << ' strcmp('
code << ' compare('
is_string_compare = true
}
}
Expand All @@ -111,9 +98,42 @@ pub fn codegen(ast parser.Ast) []string {
}

// codegen starts here
if item.keyword == 'pass' {
if item.keyword == 'pass'{
// do nothing
} else if (item.keyword == '==' || item.keyword == '!=') && is_string_compare == true {
}
else if item.keyword=="default"{
is_default=true
}
else if previous_code_block.keyword=="match"{
match_item<<item.keyword
code<<"True"
is_match=true
}

else if is_case == true {
if item.keyword=="or"{
code<<" || "
}
else if item.keyword=="and"{
code<<" && "
}
else{
if match_item.last().split('')[0]=="'" || match_item.last().split('')[0]=='"'{
code << ' compare(${match_item.last()},${item.keyword})==0 '
}
else if item.ast_type == 'variable' && item.keyword in function.variable
&& var_type(function.variable_type, keyword) == 'str' {
code << ' compare(${match_item.last()},${item.keyword})==0'
} else if item.ast_type == 'function_call'
&& func_return_if_else(keyword, ast) == ['str'] {
code << ' compare(${match_item.last()},${item.keyword})==0'
}
else{
code << ' ${match_item.last()}==${item.keyword}'
}
}
}
else if (item.keyword == '==' || item.keyword == '!=') && is_string_compare == true {
code << ','
sign = item.keyword
} else if item.ast_type == 'compare' {
Expand All @@ -125,13 +145,23 @@ pub fn codegen(ast parser.Ast) []string {
} else if item.keyword == 'break' || item.keyword == 'continue' {
code << '$item.keyword ;\n'
} else if item.keyword in loop {
if item.keyword == 'else' || item.keyword == 'default' {
if item.keyword == 'else'{
code << '$keyword '
} else {
if keyword == 'elif' {
keyword = 'else if'
} else if keyword == 'match' {
keyword = 'switch'
keyword = 'while '
last_match<<item
}
else if item.keyword =="case" && is_match == true{
is_match=false
is_case=true
keyword = "if "
}
else if item.keyword =="case" && is_match == false{
keyword = "else if "
is_case=true
}
code << '$keyword ('
}
Expand Down Expand Up @@ -245,7 +275,87 @@ pub fn codegen(ast parser.Ast) []string {
// }
// free=[]string{}
// }
if next_item.tab < item.tab || item == next_item {
if last_match.len>0 && is_match_case==true && is_loop == false {
if last_match.last().tab==next_item.tab && item!=next_item && next_item.ast_type!="new_line"{
is_match_case=false
if is_function_call == true || is_operator == true || is_return == true {
is_operator = false
is_function_call = false
is_return = false
code << ';\n'
}
if is_default==true{
code<<"\nbreak;\n"
is_default=false
}
else{
code<<"\n}"
code<<"\nbreak;\n"
}
tab_dif = int(item.tab - next_item.tab)
for _ in 1 .. tab_dif {
code << '\n}\n'
}
last_match.pop()
}
else if item.ast_type=="new_line" && ast.body.len > index + 2 && item != next_item && last_match.last().tab==next_item.tab{
tab_dif = int(item.tab - ast.body[index + 2].tab)
if is_function_call == true || is_operator == true || is_return == true {
is_operator = false
is_function_call = false
is_return = false
code << ';\n'
}
if is_default==true{
code<<"\nbreak;\n"
is_default=false
}
else{
code<<"\n}"
code<<"\nbreak;\n"
}
for _ in 1 .. tab_dif {
code << '\n}\n'
}
last_match.pop()
}
else if item==next_item{
tab_dif = int(item.tab)
for _ in last_match{
if is_default==true{
code<<"\nbreak;\n"
is_default=false
}
else {
code<<"\n}"
code<<"\nbreak;\n"
}
tab_dif--
}
for _ in 0 .. tab_dif {
code << '\n}\n'
}
}
else if next_item.ast_type == 'new_line' && ast.body.len > index + 2
&& item != next_item && is_loop == false {
tab_dif = int(item.tab - ast.body[index + 2].tab)
if is_function_call == true || is_operator == true || is_return == true {
is_operator = false
is_function_call = false
is_return = false
code << ';\n'
}
for _ in 0 .. tab_dif {
code << '\n}\n'
}
} else if next_item.direction == 'left' && item != next_item {
tab_dif = int(item.tab - next_item.tab)
for _ in 0 .. tab_dif {
code << '\n}\n'
}
}
}
else if next_item.tab < item.tab || item == next_item {
if next_item == item {
tab_dif = int(item.tab)
for _ in 0 .. tab_dif {
Expand Down
2 changes: 1 addition & 1 deletion swallow/parser/parser.v
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn parser(code []string) (Ast, string) {
operater := ['=', '==', '+', '-', '*', '/', '^', '//', '%', '>', '<', '>=', '<=', '!=', '++',
'--', '&', '|', '~', '<<', '>>', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '&=', '|=',
'^=']
loop := ['if', 'while', 'elif', 'else', 'for', 'match', 'case', 'default']
loop := ['if', 'while', 'elif', 'else', 'for', 'match', 'case','default']
logic := ['and', 'or', 'not', 'in', 'is']
error_handler := ['try', 'except', 'finally']
variable := '_variable'
Expand Down
3 changes: 3 additions & 0 deletions swallow/tests/if_else_match.sw
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ def main():
case 2:
print("It is 2\n")
break
case 3:
print("It is 2\n")
break
default:
print("I dont know what it is\n")
break
Expand Down
20 changes: 20 additions & 0 deletions swallow/tests/match_case.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
def main():
match "hi":
case "hi" or "Hi":
print("ok\n")
else:
print("Error\n")
match 100.6:
case 10.7:
print("Error\n")
case 100.6:
print("OK\n")
default:
print("Will always be executed if you dont add break in case\n")
match "saptak":
case "x":
match "bhoumik":
case "y":
print("Something is wrong")
default:
print("Something is wrong")
2 changes: 2 additions & 0 deletions swallow/tests/new_line.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def main():
print("Hello");
10 changes: 10 additions & 0 deletions swallow/tests/string.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def main():
if "a"==NULL:
print("Not ok")
if "a"!=NULL:
print("Ok\n")
str a=NULL
if a!=NULL:
print("Not Ok\n")
if a==NULL:
print("All ok")
7 changes: 6 additions & 1 deletion swallow/tokenizer/process_tokens.v
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,12 @@ pub fn process_tokens(list []string) []string {
} else if item == ' ' && is_tab == true {
ultimate_result << item
} else {
ultimate_result << item
if item ==";"{
ultimate_result << r"\n"
}
else{
ultimate_result << item
}
}
}
return remove_extra_return(ultimate_result)
Expand Down

0 comments on commit 093a0d5

Please sign in to comment.