Skip to content

Commit

Permalink
Merge pull request #140 from myuon/issue-138
Browse files Browse the repository at this point in the history
  • Loading branch information
myuon authored Sep 28, 2023
2 parents 0efee33 + dc7d3e2 commit defd355
Show file tree
Hide file tree
Showing 11 changed files with 313 additions and 23 deletions.
9 changes: 9 additions & 0 deletions quartz/ast.qz
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,15 @@ enum Expression {
type_: Type,
},
t_try: LExpression,
t_index: struct {
expr: LExpression,
expr_type: Type?,
index: LExpression,
},
t_unload: struct {
expr: LExpression,
expr_type: Type,
},
}

module Expression {
Expand Down
108 changes: 105 additions & 3 deletions quartz/ir_code_gen.qz
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ module IrCodeGenerator {
IrTerm {
t_i32: 0,
},
).try
).try,
).try,
self.let_pattern(
pat.data.t_or!.rhs,
Expand All @@ -992,7 +992,7 @@ module IrCodeGenerator {
IrTerm {
t_i32: 1,
},
).try
).try,
).try,
),
},
Expand Down Expand Up @@ -1036,7 +1036,7 @@ module IrCodeGenerator {
t_discard: self.expression(stm.t_expr!.expr).try,
};
} else if stm.t_assign != nil {
let lhs = self.expression(stm.t_assign!.lhs).try;
let lhs = self.expression_left_value(stm.t_assign!.lhs).try;
let rhs = self.expression(stm.t_assign!.rhs).try;
if stm.t_assign!.rhs_type == nil {
return _ or error::new("expected rhs type");
Expand Down Expand Up @@ -2538,11 +2538,113 @@ module IrCodeGenerator {
terms: elements,
},
};
} else if expr.t_index != nil {
let offset = self.expression(expr.t_index!.index).try;

let t = expr.t_index!.expr_type!;
if t.t_ptr != nil {
return IrTerm {
t_load: struct {
type_: IrType::new(t.t_ptr!),
address: term,
offset: IrCodeGenerator::wrap_mult_sizeof(IrType::new(t.t_ptr!), offset),
},
};
} else if t.t_vec != nil {
let symbol = "quartz_std_vec_index";
if t.t_vec!.t_byte != nil {
panic("byte indexing not implemented");
}

return IrTerm {
t_load: struct {
type_: IrType::new(t.t_vec!),
address: IrTerm {
t_call: IrCall {
callee: IrTerm {
t_ident: symbol,
},
args: make[vec[IrTerm]](self.expression(expr.t_index!.expr).try, offset),
},
},
offset: IrTerm {
t_i32: 0,
},
},
};
} else if t.t_map != nil {
let symbol = "quartz_std_map_index";

return IrTerm {
t_load: struct {
type_: IrType::new(t.t_map!.value),
address: IrTerm {
t_call: IrCall {
callee: IrTerm {
t_ident: symbol,
},
args: make[vec[IrTerm]](self.expression(expr.t_index!.expr).try, offset),
},
},
offset: IrTerm {
t_i32: 0,
},
},
};
} else {
return panic("index not implemented: {}", expr.to_string());
}
} else if expr.t_unload != nil {
let term = self.expression(expr.t_unload!.expr).try;

if term.t_load == nil {
return panic("unload expected t_load: {}", expr.to_string());
} else {
return IrTerm {
t_call: IrCall {
callee: IrTerm {
t_ident: "add",
},
args: make[vec[IrTerm]](term.t_load!.address, term.t_load!.offset),
},
};
}
}

return panic("expression exhausted: {}", expr.to_string());
}

fun expression_left_value(self, lexpr: LExpression): IrTerm or error {
let expr = lexpr.data;
if expr.t_index != nil {
let offset = self.expression(expr.t_index!.index).try;

let t = expr.t_index!.expr_type!;
if t.t_map != nil {
let symbol = "quartz_std_map_index_lhs";

return IrTerm {
t_load: struct {
type_: IrType::new(t.t_map!.value),
address: IrTerm {
t_call: IrCall {
callee: IrTerm {
t_ident: symbol,
},
args: make[vec[IrTerm]](self.expression(expr.t_index!.expr).try, offset),
},
},
offset: IrTerm {
t_i32: 0,
},
},
};
}
}

return self.expression(lexpr).try;
}

fun register_string(self, str: string): IrTerm {
let index = self.strings.get_or_insert(str);

Expand Down
2 changes: 1 addition & 1 deletion quartz/main.qz
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ module CliCommand {
}

fun start(): nil or error {
let compiler_version = "2.12.0";
let compiler_version = "2.13.0";

let args = args();
let command or err = CliCommand::parse(args.slice(1, args.length));
Expand Down
80 changes: 62 additions & 18 deletions quartz/parser.qz
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,31 @@ module Parser {
}
let end_token = self.expect("rparen").try;

if current.data.t_ident != nil {
if current.data.t_ident!.name == "unload" {
if args.length != 1 {
return _ or error::new(format("Expected 1 argument for unload, got {}", args.length.to_string()));
}

current = LExpression {
data: Expression {
t_unload: struct {
expr: args.at(0),
expr_type: Type {
t_omit: true,
},
},
},
location: Location {
start: current.location.start,
end: end_token.location.end,
},
};

continue;
}
}

current = LExpression {
data: Expression {
t_call: struct {
Expand Down Expand Up @@ -1688,7 +1713,7 @@ module Parser {
let end_token = self.expect("rparen").try;

let ident = current.data.t_ident!.name;
if ident.equal("make") {
if ident == "make" {
current = LExpression {
data: Expression {
t_make: struct {
Expand All @@ -1701,7 +1726,7 @@ module Parser {
end: end_token.location.end,
},
};
} else if ident.equal("sizeof") {
} else if ident == "sizeof" {
current = LExpression {
data: Expression {
t_sizeof: struct {
Expand Down Expand Up @@ -1982,7 +2007,8 @@ module Parser {
}

fun dot_after(self, current: LExpression): LExpression or error {
if self.peek().try.lexeme.equal("try") {
let peeked = self.peek().try;
if peeked.lexeme == "try" {
let end_token = self.expect("try").try;

return LExpression {
Expand All @@ -1994,24 +2020,42 @@ module Parser {
end: end_token.location.end,
},
};
}
} else if peeked.lexeme == "lparen" {
self.expect("lparen").try;
let expr = self.expression().try;
let end_token = self.expect("rparen").try;

let field = self.ident().try;
return LExpression {
data: Expression {
t_index: struct {
expr: current,
expr_type: nil as Type?,
index: expr,
},
},
location: Location {
start: current.location.start,
end: end_token.location.end,
},
};
} else {
let field = self.ident().try;

return LExpression {
data: Expression {
t_project: struct {
expr: current,
field: field,
type_: nil as Type?,
resolved_path: nil,
return LExpression {
data: Expression {
t_project: struct {
expr: current,
field: field,
type_: nil as Type?,
resolved_path: nil,
},
},
},
location: Location {
start: current.location.start,
end: field.location.end,
},
};
location: Location {
start: current.location.start,
end: field.location.end,
},
};
}
}

fun span_location(self, start: Token, end: Token): Location {
Expand Down
2 changes: 1 addition & 1 deletion quartz/preprocessor.qz
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ module Preprocessor {
if attr.name.data == "build_if" {
let result = self.interpret_bool(attr.args.at(0)).try;
if !result {
// m.decls.at(index + 1) = LDecl {..} is not working🤔
// FIXME: m.decls.at(index + 1) = LDecl {..} is not working🤔
m.decls.at(index + 1).data = Decl {
t_skip: true,
};
Expand Down
Loading

0 comments on commit defd355

Please sign in to comment.