mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Implement helper methods for AST/HIR construction
This commit is contained in:
parent
ae15f95191
commit
a0714b218c
8 changed files with 114 additions and 70 deletions
|
@ -29,8 +29,8 @@ use crate::compile::{AccessKind, Name, StoreLoadKind};
|
||||||
use crate::context::eval::type_from_token_kind;
|
use crate::context::eval::type_from_token_kind;
|
||||||
use crate::error::CompileError;
|
use crate::error::CompileError;
|
||||||
use crate::hir::{
|
use crate::hir::{
|
||||||
Accessor, Args, Array, AttrDef, Attribute, BinOp, Block, Call, ClassDef, Def, DefBody, Expr,
|
Accessor, Args, Array, AttrDef, BinOp, Block, Call, ClassDef, Def, DefBody, Expr, Identifier,
|
||||||
Identifier, Lambda, Literal, Params, PosArg, Record, Signature, SubrSignature, Tuple, UnaryOp,
|
Lambda, Literal, Params, PosArg, Record, Signature, SubrSignature, Tuple, UnaryOp,
|
||||||
VarSignature, HIR,
|
VarSignature, HIR,
|
||||||
};
|
};
|
||||||
use crate::ty::free::fresh_varname;
|
use crate::ty::free::fresh_varname;
|
||||||
|
@ -1717,22 +1717,19 @@ impl CodeGenerator {
|
||||||
for field in rec.keys() {
|
for field in rec.keys() {
|
||||||
let obj =
|
let obj =
|
||||||
Expr::Accessor(Accessor::private_with_line(Str::from(¶m_name), line));
|
Expr::Accessor(Accessor::private_with_line(Str::from(¶m_name), line));
|
||||||
let expr = Expr::Accessor(Accessor::Attr(Attribute::new(
|
let expr = obj.attr_expr(Identifier::bare(
|
||||||
obj,
|
Some(Token::dummy()),
|
||||||
Identifier::bare(
|
VarName::from_str(field.symbol.clone()),
|
||||||
Some(Token::dummy()),
|
));
|
||||||
VarName::from_str(field.symbol.clone()),
|
|
||||||
),
|
|
||||||
)));
|
|
||||||
let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line));
|
let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line));
|
||||||
let dot = if field.vis.is_private() {
|
let dot = if field.vis.is_private() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Token::dummy())
|
Some(Token::dummy())
|
||||||
};
|
};
|
||||||
let attr = Accessor::Attr(Attribute::new(
|
let attr = obj.attr(Identifier::bare(
|
||||||
obj,
|
dot,
|
||||||
Identifier::bare(dot, VarName::from_str(field.symbol.clone())),
|
VarName::from_str(field.symbol.clone()),
|
||||||
));
|
));
|
||||||
let attr_def = AttrDef::new(attr, Block::new(vec![expr]));
|
let attr_def = AttrDef::new(attr, Block::new(vec![expr]));
|
||||||
attrs.push(Expr::AttrDef(attr_def));
|
attrs.push(Expr::AttrDef(attr_def));
|
||||||
|
@ -1769,12 +1766,8 @@ impl CodeGenerator {
|
||||||
let mut new_ident =
|
let mut new_ident =
|
||||||
Identifier::bare(None, VarName::from_str_and_line(Str::ever("__new__"), line));
|
Identifier::bare(None, VarName::from_str_and_line(Str::ever("__new__"), line));
|
||||||
new_ident.vi.py_name = Some(Str::ever("__call__"));
|
new_ident.vi.py_name = Some(Str::ever("__call__"));
|
||||||
let class_new = Expr::Accessor(Accessor::attr(class, new_ident));
|
let class_new = class.attr_expr(new_ident);
|
||||||
let call = Expr::Call(Call::new(
|
let call = class_new.call_expr(Args::new(vec![arg], None, vec![], None));
|
||||||
class_new,
|
|
||||||
None,
|
|
||||||
Args::new(vec![arg], None, vec![], None),
|
|
||||||
));
|
|
||||||
let block = Block::new(vec![call]);
|
let block = Block::new(vec![call]);
|
||||||
let body = DefBody::new(Token::dummy(), block, DefId(0));
|
let body = DefBody::new(Token::dummy(), block, DefId(0));
|
||||||
self.emit_subr_def(Some(class_ident.inspect()), sig, body);
|
self.emit_subr_def(Some(class_ident.inspect()), sig, body);
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl HIRDesugarer {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|expr| match expr {
|
.map(|expr| match expr {
|
||||||
Expr::Def(def) => {
|
Expr::Def(def) => {
|
||||||
let acc = Accessor::attr(class.clone(), def.sig.into_ident());
|
let acc = class.clone().attr(def.sig.into_ident());
|
||||||
let attr_def = AttrDef::new(acc, def.body.block);
|
let attr_def = AttrDef::new(acc, def.body.block);
|
||||||
Expr::AttrDef(attr_def)
|
Expr::AttrDef(attr_def)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1836,6 +1836,33 @@ impl Expr {
|
||||||
pub fn is_type_asc(&self) -> bool {
|
pub fn is_type_asc(&self) -> bool {
|
||||||
matches!(self, Expr::TypeAsc(_))
|
matches!(self, Expr::TypeAsc(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn call(self, args: Args) -> Call {
|
||||||
|
match self {
|
||||||
|
Self::Accessor(Accessor::Attr(attr)) => Call::new(*attr.obj, Some(attr.ident), args),
|
||||||
|
other => Call::new(other, None, args),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call_expr(self, args: Args) -> Self {
|
||||||
|
Self::Call(self.call(args))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn attr(self, ident: Identifier) -> Accessor {
|
||||||
|
Accessor::attr(self, ident)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn attr_expr(self, ident: Identifier) -> Self {
|
||||||
|
Self::Accessor(self.attr(ident))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_asc(self, t_spec: TypeSpec) -> TypeAscription {
|
||||||
|
TypeAscription::new(self, t_spec)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_asc_expr(self, t_spec: TypeSpec) -> Self {
|
||||||
|
Self::TypeAsc(self.type_asc(t_spec))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Toplevel grammar unit
|
/// Toplevel grammar unit
|
||||||
|
|
|
@ -185,7 +185,7 @@ impl<'a> Linker<'a> {
|
||||||
let module_type =
|
let module_type =
|
||||||
Expr::Accessor(Accessor::private_with_line(Str::ever("#ModuleType"), line));
|
Expr::Accessor(Accessor::private_with_line(Str::ever("#ModuleType"), line));
|
||||||
let args = Args::new(vec![PosArg::new(mod_name.clone())], None, vec![], None);
|
let args = Args::new(vec![PosArg::new(mod_name.clone())], None, vec![], None);
|
||||||
let block = Block::new(vec![Expr::Call(Call::new(module_type, None, args))]);
|
let block = Block::new(vec![module_type.call_expr(args)]);
|
||||||
let tmp =
|
let tmp =
|
||||||
Identifier::private_with_line(Str::from(fresh_varname()), expr.ln_begin().unwrap());
|
Identifier::private_with_line(Str::from(fresh_varname()), expr.ln_begin().unwrap());
|
||||||
let mod_def = Expr::Def(Def::new(
|
let mod_def = Expr::Def(Def::new(
|
||||||
|
@ -194,9 +194,9 @@ impl<'a> Linker<'a> {
|
||||||
));
|
));
|
||||||
let module = Expr::Accessor(Accessor::Ident(tmp));
|
let module = Expr::Accessor(Accessor::Ident(tmp));
|
||||||
let __dict__ = Identifier::public("__dict__");
|
let __dict__ = Identifier::public("__dict__");
|
||||||
let m_dict = Expr::Accessor(Accessor::attr(module.clone(), __dict__));
|
let m_dict = module.clone().attr_expr(__dict__);
|
||||||
let locals = Expr::Accessor(Accessor::public_with_line(Str::ever("locals"), line));
|
let locals = Expr::Accessor(Accessor::public_with_line(Str::ever("locals"), line));
|
||||||
let locals_call = Expr::Call(Call::new(locals, None, Args::empty()));
|
let locals_call = locals.call_expr(Args::empty());
|
||||||
let args = Args::new(vec![PosArg::new(locals_call)], None, vec![], None);
|
let args = Args::new(vec![PosArg::new(locals_call)], None, vec![], None);
|
||||||
let mod_update = Expr::Call(Call::new(
|
let mod_update = Expr::Call(Call::new(
|
||||||
m_dict.clone(),
|
m_dict.clone(),
|
||||||
|
@ -210,7 +210,7 @@ impl<'a> Linker<'a> {
|
||||||
vec![],
|
vec![],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let exec_code = Expr::Call(Call::new(exec, None, args));
|
let exec_code = exec.call_expr(args);
|
||||||
let compound = Block::new(vec![mod_def, mod_update, exec_code, module]);
|
let compound = Block::new(vec![mod_def, mod_update, exec_code, module]);
|
||||||
*expr = Expr::Compound(compound);
|
*expr = Expr::Compound(compound);
|
||||||
}
|
}
|
||||||
|
@ -256,15 +256,13 @@ impl<'a> Linker<'a> {
|
||||||
args.insert_pos(0, PosArg::new(mod_name));
|
args.insert_pos(0, PosArg::new(mod_name));
|
||||||
let line = expr.ln_begin().unwrap_or(0);
|
let line = expr.ln_begin().unwrap_or(0);
|
||||||
for attr in comps {
|
for attr in comps {
|
||||||
*expr = Expr::Accessor(Accessor::attr(
|
*expr = mem::replace(expr, Expr::Code(Block::empty())).attr_expr(
|
||||||
// instead of mem::take(),
|
|
||||||
mem::replace(expr, Expr::Code(Block::empty())),
|
|
||||||
Identifier::public_with_line(
|
Identifier::public_with_line(
|
||||||
Token::dummy(),
|
Token::dummy(),
|
||||||
Str::rc(attr.as_os_str().to_str().unwrap()),
|
Str::rc(attr.as_os_str().to_str().unwrap()),
|
||||||
line,
|
line,
|
||||||
),
|
),
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1418,7 +1418,7 @@ impl ASTLowerer {
|
||||||
expr.loc(),
|
expr.loc(),
|
||||||
Some(&Str::from(expr.to_string())),
|
Some(&Str::from(expr.to_string())),
|
||||||
)?;
|
)?;
|
||||||
Ok(hir::TypeAscription::new(expr, tasc.t_spec))
|
Ok(expr.type_asc(tasc.t_spec))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call.obj == Accessor cannot be type inferred by itself (it can only be inferred with arguments)
|
// Call.obj == Accessor cannot be type inferred by itself (it can only be inferred with arguments)
|
||||||
|
@ -1527,8 +1527,7 @@ impl ASTLowerer {
|
||||||
ast::Expr::Accessor(ast::Accessor::Attr(attr)) => {
|
ast::Expr::Accessor(ast::Accessor::Attr(attr)) => {
|
||||||
let obj = self.fake_lower_obj(*attr.obj)?;
|
let obj = self.fake_lower_obj(*attr.obj)?;
|
||||||
let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name);
|
let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name);
|
||||||
let acc = hir::Accessor::attr(obj, ident);
|
Ok(obj.attr_expr(ident))
|
||||||
Ok(hir::Expr::Accessor(acc))
|
|
||||||
}
|
}
|
||||||
other => Err(LowerErrors::from(LowerError::declare_error(
|
other => Err(LowerErrors::from(LowerError::declare_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
|
@ -1596,10 +1595,7 @@ impl ASTLowerer {
|
||||||
let py_name = Str::rc(ident.inspect().trim_end_matches('!'));
|
let py_name = Str::rc(ident.inspect().trim_end_matches('!'));
|
||||||
let vi = VarInfo::new(t, muty, vis, VarKind::Declared, None, None, Some(py_name));
|
let vi = VarInfo::new(t, muty, vis, VarKind::Declared, None, None, Some(py_name));
|
||||||
let ident = hir::Identifier::new(ident.dot, ident.name, None, vi);
|
let ident = hir::Identifier::new(ident.dot, ident.name, None, vi);
|
||||||
Ok(hir::TypeAscription::new(
|
Ok(hir::Expr::Accessor(hir::Accessor::Ident(ident)).type_asc(tasc.t_spec))
|
||||||
hir::Expr::Accessor(hir::Accessor::Ident(ident)),
|
|
||||||
tasc.t_spec,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
ast::Expr::Accessor(ast::Accessor::Attr(attr)) => {
|
ast::Expr::Accessor(ast::Accessor::Attr(attr)) => {
|
||||||
let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!'));
|
let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!'));
|
||||||
|
@ -1625,11 +1621,8 @@ impl ASTLowerer {
|
||||||
let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!'));
|
let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!'));
|
||||||
let vi = VarInfo::new(t, muty, vis, VarKind::Declared, None, None, Some(py_name));
|
let vi = VarInfo::new(t, muty, vis, VarKind::Declared, None, None, Some(py_name));
|
||||||
let ident = hir::Identifier::new(attr.ident.dot, attr.ident.name, None, vi);
|
let ident = hir::Identifier::new(attr.ident.dot, attr.ident.name, None, vi);
|
||||||
let attr = hir::Accessor::attr(obj, ident);
|
let attr = obj.attr_expr(ident);
|
||||||
Ok(hir::TypeAscription::new(
|
Ok(attr.type_asc(tasc.t_spec))
|
||||||
hir::Expr::Accessor(attr),
|
|
||||||
tasc.t_spec,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
other => Err(LowerErrors::from(LowerError::declare_error(
|
other => Err(LowerErrors::from(LowerError::declare_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
|
|
|
@ -3222,6 +3222,49 @@ impl Expr {
|
||||||
pub fn static_local(name: &'static str) -> Self {
|
pub fn static_local(name: &'static str) -> Self {
|
||||||
Self::Accessor(Accessor::local(Token::static_symbol(name)))
|
Self::Accessor(Accessor::local(Token::static_symbol(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn attr(self, ident: Identifier) -> Accessor {
|
||||||
|
Accessor::attr(self, ident)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn attr_expr(self, ident: Identifier) -> Self {
|
||||||
|
Self::Accessor(self.attr(ident))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subscr(self, index: Expr, r_sqbr: Token) -> Accessor {
|
||||||
|
Accessor::subscr(self, index, r_sqbr)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subscr_expr(self, index: Expr, r_sqbr: Token) -> Self {
|
||||||
|
Self::Accessor(self.subscr(index, r_sqbr))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tuple_attr(self, index: Literal) -> Accessor {
|
||||||
|
Accessor::tuple_attr(self, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tuple_attr_expr(self, index: Literal) -> Self {
|
||||||
|
Self::Accessor(self.tuple_attr(index))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call(self, args: Args) -> Call {
|
||||||
|
match self {
|
||||||
|
Self::Accessor(Accessor::Attr(attr)) => Call::new(*attr.obj, Some(attr.ident), args),
|
||||||
|
other => Call::new(other, None, args),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call_expr(self, args: Args) -> Self {
|
||||||
|
Self::Call(self.call(args))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_asc(self, op: Token, t_spec: TypeSpec) -> TypeAscription {
|
||||||
|
TypeAscription::new(self, op, t_spec)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_asc_expr(self, op: Token, t_spec: TypeSpec) -> Self {
|
||||||
|
Self::TypeAsc(self.type_asc(op, t_spec))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -15,8 +15,8 @@ use crate::ast::{
|
||||||
DefBody, DefId, Dict, Expr, Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal,
|
DefBody, DefId, Dict, Expr, Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal,
|
||||||
Methods, Module, NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord, NormalSet,
|
Methods, Module, NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord, NormalSet,
|
||||||
NormalTuple, ParamPattern, Params, PosArg, Record, RecordAttrs, Set as astSet, SetWithLength,
|
NormalTuple, ParamPattern, Params, PosArg, Record, RecordAttrs, Set as astSet, SetWithLength,
|
||||||
ShortenedRecord, Signature, SubrSignature, Tuple, TypeAscription, TypeBoundSpecs, TypeSpec,
|
ShortenedRecord, Signature, SubrSignature, Tuple, TypeBoundSpecs, TypeSpec, UnaryOp, VarName,
|
||||||
UnaryOp, VarName, VarPattern, VarRecordAttr, VarSignature,
|
VarPattern, VarRecordAttr, VarSignature,
|
||||||
};
|
};
|
||||||
use crate::token::{Token, TokenKind};
|
use crate::token::{Token, TokenKind};
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ impl Desugarer {
|
||||||
}
|
}
|
||||||
Expr::TypeAsc(tasc) => {
|
Expr::TypeAsc(tasc) => {
|
||||||
let expr = desugar(*tasc.expr);
|
let expr = desugar(*tasc.expr);
|
||||||
Expr::TypeAsc(TypeAscription::new(expr, tasc.op, tasc.t_spec))
|
expr.type_asc_expr(tasc.op, tasc.t_spec)
|
||||||
}
|
}
|
||||||
Expr::Methods(method_defs) => {
|
Expr::Methods(method_defs) => {
|
||||||
let mut new_defs = vec![];
|
let mut new_defs = vec![];
|
||||||
|
@ -323,7 +323,7 @@ impl Desugarer {
|
||||||
vec![],
|
vec![],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let call = Call::new(match_symbol, None, args);
|
let call = match_symbol.call(args);
|
||||||
(call, return_t_spec)
|
(call, return_t_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,9 +439,7 @@ impl Desugarer {
|
||||||
) {
|
) {
|
||||||
let obj = Expr::local(buf_name, sig.ln_begin().unwrap(), sig.col_begin().unwrap());
|
let obj = Expr::local(buf_name, sig.ln_begin().unwrap(), sig.col_begin().unwrap());
|
||||||
let acc = match buf_index {
|
let acc = match buf_index {
|
||||||
BufIndex::Tuple(n) => {
|
BufIndex::Tuple(n) => obj.tuple_attr(Literal::nat(n, sig.ln_begin().unwrap())),
|
||||||
Accessor::tuple_attr(obj, Literal::nat(n, sig.ln_begin().unwrap()))
|
|
||||||
}
|
|
||||||
BufIndex::Array(n) => {
|
BufIndex::Array(n) => {
|
||||||
let r_brace = Token::new(
|
let r_brace = Token::new(
|
||||||
TokenKind::RBrace,
|
TokenKind::RBrace,
|
||||||
|
@ -449,13 +447,9 @@ impl Desugarer {
|
||||||
sig.ln_begin().unwrap(),
|
sig.ln_begin().unwrap(),
|
||||||
sig.col_begin().unwrap(),
|
sig.col_begin().unwrap(),
|
||||||
);
|
);
|
||||||
Accessor::subscr(
|
obj.subscr(Expr::Lit(Literal::nat(n, sig.ln_begin().unwrap())), r_brace)
|
||||||
obj,
|
|
||||||
Expr::Lit(Literal::nat(n, sig.ln_begin().unwrap())),
|
|
||||||
r_brace,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
BufIndex::Record(attr) => Accessor::attr(obj, attr.clone()),
|
BufIndex::Record(attr) => obj.attr(attr.clone()),
|
||||||
};
|
};
|
||||||
let id = DefId(get_hash(&(&acc, buf_name)));
|
let id = DefId(get_hash(&(&acc, buf_name)));
|
||||||
let block = Block::new(vec![Expr::Accessor(acc)]);
|
let block = Block::new(vec![Expr::Accessor(acc)]);
|
||||||
|
|
|
@ -885,7 +885,7 @@ impl Parser {
|
||||||
Some(arg) if arg.is(Symbol) || arg.category_is(TC::Literal) => {
|
Some(arg) if arg.is(Symbol) || arg.category_is(TC::Literal) => {
|
||||||
let args = self.try_reduce_args(false).map_err(|_| self.stack_dec())?;
|
let args = self.try_reduce_args(false).map_err(|_| self.stack_dec())?;
|
||||||
let obj = enum_unwrap!(stack.pop(), Some:(ExprOrOp::Expr:(_)));
|
let obj = enum_unwrap!(stack.pop(), Some:(ExprOrOp::Expr:(_)));
|
||||||
stack.push(ExprOrOp::Expr(Expr::Call(Call::new(obj, None, args))));
|
stack.push(ExprOrOp::Expr(obj.call_expr(args)));
|
||||||
}
|
}
|
||||||
Some(op) if op.category_is(TC::DefOp) => {
|
Some(op) if op.category_is(TC::DefOp) => {
|
||||||
let op = self.lpop();
|
let op = self.lpop();
|
||||||
|
@ -934,7 +934,7 @@ impl Parser {
|
||||||
.try_reduce_expr(false, false, false, false)
|
.try_reduce_expr(false, false, false, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
let t_spec = Self::expr_to_type_spec(t_spec).map_err(|e| self.errs.push(e))?;
|
let t_spec = Self::expr_to_type_spec(t_spec).map_err(|e| self.errs.push(e))?;
|
||||||
let expr = Expr::TypeAsc(TypeAscription::new(lhs, op, t_spec));
|
let expr = lhs.type_asc_expr(op, t_spec);
|
||||||
stack.push(ExprOrOp::Expr(expr));
|
stack.push(ExprOrOp::Expr(expr));
|
||||||
}
|
}
|
||||||
Some(op) if op.category_is(TC::BinOp) => {
|
Some(op) if op.category_is(TC::BinOp) => {
|
||||||
|
@ -985,8 +985,7 @@ impl Parser {
|
||||||
stack.push(ExprOrOp::Expr(Expr::Call(call)));
|
stack.push(ExprOrOp::Expr(Expr::Call(call)));
|
||||||
} else {
|
} else {
|
||||||
let ident = Identifier::new(None, VarName::new(symbol));
|
let ident = Identifier::new(None, VarName::new(symbol));
|
||||||
let acc = Accessor::attr(obj, ident);
|
stack.push(ExprOrOp::Expr(obj.attr_expr(ident)));
|
||||||
stack.push(ExprOrOp::Expr(Expr::Accessor(acc)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line_break if line_break.is(Newline) => {
|
line_break if line_break.is(Newline) => {
|
||||||
|
@ -1049,13 +1048,12 @@ impl Parser {
|
||||||
let mut call = Expr::Call(Call::new(obj, Some(ident), args));
|
let mut call = Expr::Call(Call::new(obj, Some(ident), args));
|
||||||
while let Some(res) = self.opt_reduce_args(false) {
|
while let Some(res) = self.opt_reduce_args(false) {
|
||||||
let args = res.map_err(|_| self.stack_dec())?;
|
let args = res.map_err(|_| self.stack_dec())?;
|
||||||
call = Expr::Call(Call::new(call, None, args));
|
call = call.call_expr(args);
|
||||||
}
|
}
|
||||||
stack.push(ExprOrOp::Expr(call));
|
stack.push(ExprOrOp::Expr(call));
|
||||||
} else {
|
} else {
|
||||||
let ident = Identifier::new(Some(vis), VarName::new(symbol));
|
let ident = Identifier::new(Some(vis), VarName::new(symbol));
|
||||||
let acc = Accessor::attr(obj, ident);
|
stack.push(ExprOrOp::Expr(obj.attr_expr(ident)));
|
||||||
stack.push(ExprOrOp::Expr(Expr::Accessor(acc)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line_break if line_break.is(Newline) => {
|
line_break if line_break.is(Newline) => {
|
||||||
|
@ -1201,7 +1199,7 @@ impl Parser {
|
||||||
.try_reduce_expr(false, in_type_args, in_brace, false)
|
.try_reduce_expr(false, in_type_args, in_brace, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
let t_spec = Self::expr_to_type_spec(t_spec).map_err(|e| self.errs.push(e))?;
|
let t_spec = Self::expr_to_type_spec(t_spec).map_err(|e| self.errs.push(e))?;
|
||||||
let expr = Expr::TypeAsc(TypeAscription::new(lhs, op, t_spec));
|
let expr = lhs.type_asc_expr(op, t_spec);
|
||||||
stack.push(ExprOrOp::Expr(expr));
|
stack.push(ExprOrOp::Expr(expr));
|
||||||
}
|
}
|
||||||
Some(op) if op.category_is(TC::BinOp) => {
|
Some(op) if op.category_is(TC::BinOp) => {
|
||||||
|
@ -1252,8 +1250,7 @@ impl Parser {
|
||||||
stack.push(ExprOrOp::Expr(Expr::Call(call)));
|
stack.push(ExprOrOp::Expr(Expr::Call(call)));
|
||||||
} else {
|
} else {
|
||||||
let ident = Identifier::new(Some(vis), VarName::new(symbol));
|
let ident = Identifier::new(Some(vis), VarName::new(symbol));
|
||||||
let acc = Accessor::attr(obj, ident);
|
stack.push(ExprOrOp::Expr(obj.attr_expr(ident)));
|
||||||
stack.push(ExprOrOp::Expr(Expr::Accessor(acc)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
|
@ -1353,10 +1350,10 @@ impl Parser {
|
||||||
Signature::Var(var) => {
|
Signature::Var(var) => {
|
||||||
let mut last = def.body.block.pop().unwrap();
|
let mut last = def.body.block.pop().unwrap();
|
||||||
for deco in decos.into_iter() {
|
for deco in decos.into_iter() {
|
||||||
last = Expr::Call(Call::new(
|
last = deco.into_expr().call_expr(Args::new(
|
||||||
deco.into_expr(),
|
vec![PosArg::new(last)],
|
||||||
|
vec![],
|
||||||
None,
|
None,
|
||||||
Args::new(vec![PosArg::new(last)], vec![], None),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
def.body.block.push(last);
|
def.body.block.push(last);
|
||||||
|
@ -1501,11 +1498,11 @@ impl Parser {
|
||||||
match token.kind {
|
match token.kind {
|
||||||
Symbol => {
|
Symbol => {
|
||||||
let ident = Identifier::new(Some(vis), VarName::new(token));
|
let ident = Identifier::new(Some(vis), VarName::new(token));
|
||||||
obj = Expr::Accessor(Accessor::attr(obj, ident));
|
obj = obj.attr_expr(ident);
|
||||||
}
|
}
|
||||||
NatLit => {
|
NatLit => {
|
||||||
let index = Literal::from(token);
|
let index = Literal::from(token);
|
||||||
obj = Expr::Accessor(Accessor::tuple_attr(obj, index));
|
obj = obj.tuple_attr_expr(index);
|
||||||
}
|
}
|
||||||
Newline => {
|
Newline => {
|
||||||
self.restore(token);
|
self.restore(token);
|
||||||
|
@ -1527,8 +1524,7 @@ impl Parser {
|
||||||
token.content = Str::rc(&token.content[1..]);
|
token.content = Str::rc(&token.content[1..]);
|
||||||
token.kind = NatLit;
|
token.kind = NatLit;
|
||||||
token.col_begin += 1;
|
token.col_begin += 1;
|
||||||
let index = Literal::from(token);
|
obj = obj.tuple_attr_expr(Literal::from(token));
|
||||||
obj = Expr::Accessor(Accessor::tuple_attr(obj, index));
|
|
||||||
}
|
}
|
||||||
Some(t) if t.is(DblColon) && obj.col_end() == t.col_begin() => {
|
Some(t) if t.is(DblColon) && obj.col_end() == t.col_begin() => {
|
||||||
let vis = self.lpop();
|
let vis = self.lpop();
|
||||||
|
@ -1536,7 +1532,7 @@ impl Parser {
|
||||||
match token.kind {
|
match token.kind {
|
||||||
Symbol => {
|
Symbol => {
|
||||||
let ident = Identifier::new(None, VarName::new(token));
|
let ident = Identifier::new(None, VarName::new(token));
|
||||||
obj = Expr::Accessor(Accessor::attr(obj, ident));
|
obj = obj.attr_expr(ident);
|
||||||
}
|
}
|
||||||
LBrace => {
|
LBrace => {
|
||||||
self.restore(token);
|
self.restore(token);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue