mirror of
https://github.com/golang/go
synced 2024-11-26 10:08:23 -07:00
165 lines
3.4 KiB
Go
165 lines
3.4 KiB
Go
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package Expr
|
||
|
|
||
|
import Globals "globals"
|
||
|
import Universe "universe"
|
||
|
import Object "object"
|
||
|
import Type "type"
|
||
|
import AST "ast"
|
||
|
|
||
|
|
||
|
// TODO the following shortcuts below don't work due to 6g/6l bugs
|
||
|
//type Compilation Globals.Compilation
|
||
|
//type Expr Globals.Expr
|
||
|
|
||
|
|
||
|
func Error(comp *Globals.Compilation, pos int, msg string) {
|
||
|
comp.env.Error(comp, pos, msg);
|
||
|
}
|
||
|
|
||
|
|
||
|
export func Deref(comp *Globals.Compilation, x Globals.Expr) Globals.Expr {
|
||
|
switch typ := x.typ(); typ.form {
|
||
|
case Type.BAD:
|
||
|
// ignore
|
||
|
|
||
|
case Type.POINTER:
|
||
|
x = AST.NewDeref(x);
|
||
|
|
||
|
default:
|
||
|
Error(comp, x.pos(), `"*" not applicable (typ.form = ` + Type.FormStr(typ.form) + `)`);
|
||
|
x = AST.Bad;
|
||
|
}
|
||
|
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
|
||
|
export func Select(comp *Globals.Compilation, x Globals.Expr, pos int, selector string) Globals.Expr {
|
||
|
if x.typ().form == Type.POINTER {
|
||
|
x = Deref(comp, x);
|
||
|
}
|
||
|
|
||
|
switch typ := x.typ(); typ.form {
|
||
|
case Type.BAD:
|
||
|
// ignore
|
||
|
|
||
|
case Type.STRUCT, Type.INTERFACE:
|
||
|
obj := typ.scope.Lookup(selector);
|
||
|
if obj != nil {
|
||
|
x = AST.NewSelector(x.pos(), obj.typ);
|
||
|
|
||
|
} else {
|
||
|
Error(comp, pos, `no field/method "` + selector + `"`);
|
||
|
x = AST.Bad;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
Error(comp, pos, `"." not applicable (typ.form = ` + Type.FormStr(typ.form) + `)`);
|
||
|
x = AST.Bad;
|
||
|
}
|
||
|
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
|
||
|
export func AssertType(comp *Globals.Compilation, x Globals.Expr, pos int, typ *Globals.Type) Globals.Expr {
|
||
|
return AST.Bad;
|
||
|
}
|
||
|
|
||
|
|
||
|
export func Index(comp *Globals.Compilation, x, i Globals.Expr) Globals.Expr {
|
||
|
if x.typ().form == Type.POINTER {
|
||
|
x = Deref(comp, x);
|
||
|
}
|
||
|
|
||
|
switch typ := x.typ(); typ.form {
|
||
|
case Type.BAD:
|
||
|
// ignore
|
||
|
|
||
|
case Type.STRING, Type.ARRAY:
|
||
|
x = AST.Bad;
|
||
|
|
||
|
case Type.MAP:
|
||
|
if Type.Equal(typ.key, i.typ()) {
|
||
|
// x = AST.NewSubscript(x, i1);
|
||
|
x = AST.Bad;
|
||
|
|
||
|
} else {
|
||
|
Error(comp, x.pos(), "map key type mismatch");
|
||
|
x = AST.Bad;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
Error(comp, x.pos(), `"[]" not applicable (typ.form = ` + Type.FormStr(typ.form) + `)`);
|
||
|
x = AST.Bad;
|
||
|
}
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
|
||
|
export func Slice(comp *Globals.Compilation, x, i, j Globals.Expr) Globals.Expr {
|
||
|
if x.typ().form == Type.POINTER {
|
||
|
x = Deref(comp, x);
|
||
|
}
|
||
|
|
||
|
switch typ := x.typ(); typ.form {
|
||
|
case Type.BAD:
|
||
|
// ignore
|
||
|
break;
|
||
|
case Type.STRING, Type.ARRAY:
|
||
|
x = AST.Bad;
|
||
|
|
||
|
case Type.MAP:
|
||
|
if Type.Equal(typ.key, i.typ()) {
|
||
|
// x = AST.NewSubscript(x, i1);
|
||
|
x = AST.Bad;
|
||
|
|
||
|
} else {
|
||
|
Error(comp, x.pos(), "map key type mismatch");
|
||
|
x = AST.Bad;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
Error(comp, x.pos(), `"[:]" not applicable (typ.form = ` + Type.FormStr(typ.form) + `)`);
|
||
|
x = AST.Bad;
|
||
|
}
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
|
||
|
export func Call(comp *Globals.Compilation, x Globals.Expr, args *Globals.List) Globals.Expr {
|
||
|
if x.typ().form == Type.POINTER {
|
||
|
x = Deref(comp, x);
|
||
|
}
|
||
|
|
||
|
if x.op() == AST.OBJECT && x.(*AST.Object).obj.kind == Object.BUILTIN {
|
||
|
panic("builtin call - UNIMPLEMENTED");
|
||
|
}
|
||
|
|
||
|
typ := x.typ();
|
||
|
if typ.form == Type.FUNCTION || typ.form == Type.METHOD {
|
||
|
// TODO check args against parameters
|
||
|
}
|
||
|
|
||
|
return AST.Bad;
|
||
|
}
|
||
|
|
||
|
|
||
|
export func UnaryExpr(comp *Globals.Compilation, x Globals.Expr) Globals.Expr {
|
||
|
return AST.Bad;
|
||
|
}
|
||
|
|
||
|
|
||
|
export func BinaryExpr(comp *Globals.Compilation, x, y Globals.Expr) Globals.Expr {
|
||
|
e := new(AST.BinaryExpr);
|
||
|
e.typ_ = x.typ(); // TODO fix this
|
||
|
//e.op = P.tok; // TODO should we use tokens or separate operator constants?
|
||
|
e.x = x;
|
||
|
e.y = y;
|
||
|
return e;
|
||
|
}
|