Skip to content

Commit 216cff9

Browse files
committed
BinOp, BoolOp and UnaryOp
1 parent 058dc76 commit 216cff9

File tree

4 files changed

+129
-21
lines changed

4 files changed

+129
-21
lines changed

ast/dump.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ func Dump(ast Ast) string {
6767
return "<nil>"
6868
}
6969
name := ast.Type().Name
70-
if name == "ExprStmt" {
70+
switch name {
71+
case "ExprStmt":
7172
name = "Expr"
7273
}
7374
return dump(ast, name)

parser/grammar.y

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func tupleOrExpr(pos ast.Pos, elts []ast.Expr, optional_comma bool) ast.Expr {
3636
cmpop ast.CmpOp
3737
comma bool
3838
comprehensions []ast.Comprehension
39+
isExpr bool
3940
}
4041

4142
%type <obj> strings
@@ -780,34 +781,40 @@ or_test:
780781
and_test
781782
{
782783
$$ = $1
784+
$<isExpr>$ = true
783785
}
784786
| or_test OR and_test
785787
{
786-
if boolop, ok := $$.(*ast.BoolOp); ok && boolop.Op == ast.Or {
788+
if !$<isExpr>1 {
789+
boolop := $$.(*ast.BoolOp)
787790
boolop.Values = append(boolop.Values, $3)
788791
} else {
789792
$$ = &ast.BoolOp{ExprBase: ast.ExprBase{$<pos>$}, Op: ast.Or, Values: []ast.Expr{$$, $3}} // FIXME Ctx
790793
}
794+
$<isExpr>$ = false
791795
}
792796

793797
and_test:
794798
not_test
795799
{
796800
$$ = $1
801+
$<isExpr>$ = true
797802
}
798803
| and_test AND not_test
799804
{
800-
if boolop, ok := $$.(*ast.BoolOp); ok && boolop.Op == ast.And {
805+
if !$<isExpr>1 {
806+
boolop := $$.(*ast.BoolOp)
801807
boolop.Values = append(boolop.Values, $3)
802808
} else {
803809
$$ = &ast.BoolOp{ExprBase: ast.ExprBase{$<pos>$}, Op: ast.And, Values: []ast.Expr{$$, $3}} // FIXME Ctx
804810
}
811+
$<isExpr>$ = false
805812
}
806813

807814
not_test:
808815
NOT not_test
809816
{
810-
$$ = &ast.UnaryOp{ExprBase: ast.ExprBase{$<pos>$}, Op: ast.Not, Operand: $$} // FIXME Ctx
817+
$$ = &ast.UnaryOp{ExprBase: ast.ExprBase{$<pos>$}, Op: ast.Not, Operand: $2}
811818
}
812819
| comparison
813820
{
@@ -818,15 +825,18 @@ comparison:
818825
expr
819826
{
820827
$$ = $1
828+
$<isExpr>$ = true
821829
}
822830
| comparison comp_op expr
823831
{
824-
if comp, ok := $$.(*ast.Compare); ok {
832+
if !$<isExpr>1 {
833+
comp := $$.(*ast.Compare)
825834
comp.Ops = append(comp.Ops, $2)
826835
comp.Comparators = append(comp.Comparators, $3)
827836
} else{
828-
comp = &ast.Compare{ExprBase: ast.ExprBase{$<pos>$}, Left: $$, Ops: []ast.CmpOp{$2}, Comparators: []ast.Expr{$3}} // FIXME Ctx
837+
$$ = &ast.Compare{ExprBase: ast.ExprBase{$<pos>$}, Left: $$, Ops: []ast.CmpOp{$2}, Comparators: []ast.Expr{$3}}
829838
}
839+
$<isExpr>$ = false
830840
}
831841

832842
// <> LTGT isn't actually a valid comparison operator in Python. It's here for the
@@ -890,7 +900,7 @@ expr:
890900
}
891901
| expr '|' xor_expr
892902
{
893-
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.BitOr, Right: $3} // FIXME Ctx
903+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.BitOr, Right: $3}
894904
}
895905

896906
xor_expr:
@@ -900,7 +910,7 @@ xor_expr:
900910
}
901911
| xor_expr '^' and_expr
902912
{
903-
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.BitXor, Right: $3} // FIXME Ctx
913+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.BitXor, Right: $3}
904914
}
905915

906916
and_expr:
@@ -910,7 +920,7 @@ and_expr:
910920
}
911921
| and_expr '&' shift_expr
912922
{
913-
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.BitAnd, Right: $3} // FIXME Ctx
923+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.BitAnd, Right: $3}
914924
}
915925

916926
shift_expr:
@@ -920,11 +930,11 @@ shift_expr:
920930
}
921931
| shift_expr LTLT arith_expr
922932
{
923-
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.LShift, Right: $3} // FIXME Ctx
933+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.LShift, Right: $3}
924934
}
925935
| shift_expr GTGT arith_expr
926936
{
927-
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.RShift, Right: $3} // FIXME Ctx
937+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.RShift, Right: $3}
928938
}
929939

930940
arith_expr:
@@ -934,11 +944,11 @@ arith_expr:
934944
}
935945
| arith_expr '+' term
936946
{
937-
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.Add, Right: $3} // FIXME Ctx
947+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.Add, Right: $3}
938948
}
939949
| arith_expr '-' term
940950
{
941-
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.Sub, Right: $3} // FIXME Ctx
951+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.Sub, Right: $3}
942952
}
943953

944954
term:
@@ -948,33 +958,33 @@ term:
948958
}
949959
| term '*' factor
950960
{
951-
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.Mult, Right: $3} // FIXME Ctx
961+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.Mult, Right: $3}
952962
}
953963
| term '/' factor
954964
{
955-
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.Div, Right: $3} // FIXME Ctx
965+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.Div, Right: $3}
956966
}
957967
| term '%' factor
958968
{
959-
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.Modulo, Right: $3} // FIXME Ctx
969+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.Modulo, Right: $3}
960970
}
961971
| term DIVDIV factor
962972
{
963-
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.FloorDiv, Right: $3} // FIXME Ctx
973+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.FloorDiv, Right: $3}
964974
}
965975

966976
factor:
967977
'+' factor
968978
{
969-
$$ = &ast.UnaryOp{ExprBase: ast.ExprBase{$<pos>$}, Op: ast.UAdd, Operand: $2} // FIXME Ctx
979+
$$ = &ast.UnaryOp{ExprBase: ast.ExprBase{$<pos>$}, Op: ast.UAdd, Operand: $2}
970980
}
971981
| '-' factor
972982
{
973-
$$ = &ast.UnaryOp{ExprBase: ast.ExprBase{$<pos>$}, Op: ast.USub, Operand: $2} // FIXME Ctx
983+
$$ = &ast.UnaryOp{ExprBase: ast.ExprBase{$<pos>$}, Op: ast.USub, Operand: $2}
974984
}
975985
| '~' factor
976986
{
977-
$$ = &ast.UnaryOp{ExprBase: ast.ExprBase{$<pos>$}, Op: ast.Invert, Operand: $2} // FIXME Ctx
987+
$$ = &ast.UnaryOp{ExprBase: ast.ExprBase{$<pos>$}, Op: ast.Invert, Operand: $2}
978988
}
979989
| power
980990
{
@@ -990,7 +1000,7 @@ power:
9901000
| atom trailers STARSTAR factor
9911001
{
9921002
// FIXME apply trailers (if any) to atom
993-
$$ = $1
1003+
$$ = &ast.BinOp{ExprBase: ast.ExprBase{$<pos>$}, Left: $1, Op: ast.Pow, Right: $4}
9941004
}
9951005

9961006
// Trailers are half made Call, Attribute or Subscript

parser/grammar_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,49 @@ func TestGrammar(t *testing.T) {
8787
{"{ a:b for a in ab if a if b if c }", "eval", "Expression(body=DictComp(key=Name(id='a', ctx=Load()), value=Name(id='b', ctx=Load()), generators=[comprehension(target=Name(id='a', ctx=Store()), iter=Name(id='ab', ctx=Load()), ifs=[Name(id='a', ctx=Load()), Name(id='b', ctx=Load()), Name(id='c', ctx=Load())])]))"},
8888
{"{ a:b for a in ab for A in AB }", "eval", "Expression(body=DictComp(key=Name(id='a', ctx=Load()), value=Name(id='b', ctx=Load()), generators=[comprehension(target=Name(id='a', ctx=Store()), iter=Name(id='ab', ctx=Load()), ifs=[]), comprehension(target=Name(id='A', ctx=Store()), iter=Name(id='AB', ctx=Load()), ifs=[])]))"},
8989
{"{ a:b for a in ab if a if b for A in AB if c }", "eval", "Expression(body=DictComp(key=Name(id='a', ctx=Load()), value=Name(id='b', ctx=Load()), generators=[comprehension(target=Name(id='a', ctx=Store()), iter=Name(id='ab', ctx=Load()), ifs=[Name(id='a', ctx=Load()), Name(id='b', ctx=Load())]), comprehension(target=Name(id='A', ctx=Store()), iter=Name(id='AB', ctx=Load()), ifs=[Name(id='c', ctx=Load())])]))"},
90+
{"a|b", "eval", "Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=BitOr(), right=Name(id='b', ctx=Load())))"},
91+
{"a^b", "eval", "Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=BitXor(), right=Name(id='b', ctx=Load())))"},
92+
{"a&b", "eval", "Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=BitAnd(), right=Name(id='b', ctx=Load())))"},
93+
{"a<<b", "eval", "Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=LShift(), right=Name(id='b', ctx=Load())))"},
94+
{"a>>b", "eval", "Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=RShift(), right=Name(id='b', ctx=Load())))"},
95+
{"a+b", "eval", "Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Name(id='b', ctx=Load())))"},
96+
{"a-b", "eval", "Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=Sub(), right=Name(id='b', ctx=Load())))"},
97+
{"a*b", "eval", "Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=Mult(), right=Name(id='b', ctx=Load())))"},
98+
{"a/b", "eval", "Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=Div(), right=Name(id='b', ctx=Load())))"},
99+
{"a//b", "eval", "Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=FloorDiv(), right=Name(id='b', ctx=Load())))"},
100+
{"a**b", "eval", "Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=Pow(), right=Name(id='b', ctx=Load())))"},
101+
{"not a", "eval", "Expression(body=UnaryOp(op=Not(), operand=Name(id='a', ctx=Load())))"},
102+
{"+a", "eval", "Expression(body=UnaryOp(op=UAdd(), operand=Name(id='a', ctx=Load())))"},
103+
{"-a", "eval", "Expression(body=UnaryOp(op=USub(), operand=Name(id='a', ctx=Load())))"},
104+
{"~a", "eval", "Expression(body=UnaryOp(op=Invert(), operand=Name(id='a', ctx=Load())))"},
105+
{"a and b", "eval", "Expression(body=BoolOp(op=And(), values=[Name(id='a', ctx=Load()), Name(id='b', ctx=Load())]))"},
106+
{"a or b", "eval", "Expression(body=BoolOp(op=Or(), values=[Name(id='a', ctx=Load()), Name(id='b', ctx=Load())]))"},
107+
{"a or b or c", "eval", "Expression(body=BoolOp(op=Or(), values=[Name(id='a', ctx=Load()), Name(id='b', ctx=Load()), Name(id='c', ctx=Load())]))"},
108+
{"(a or b) or c", "eval", "Expression(body=BoolOp(op=Or(), values=[BoolOp(op=Or(), values=[Name(id='a', ctx=Load()), Name(id='b', ctx=Load())]), Name(id='c', ctx=Load())]))"},
109+
{"a or (b or c)", "eval", "Expression(body=BoolOp(op=Or(), values=[Name(id='a', ctx=Load()), BoolOp(op=Or(), values=[Name(id='b', ctx=Load()), Name(id='c', ctx=Load())])]))"},
110+
{"a and b and c", "eval", "Expression(body=BoolOp(op=And(), values=[Name(id='a', ctx=Load()), Name(id='b', ctx=Load()), Name(id='c', ctx=Load())]))"},
111+
{"(a and b) and c", "eval", "Expression(body=BoolOp(op=And(), values=[BoolOp(op=And(), values=[Name(id='a', ctx=Load()), Name(id='b', ctx=Load())]), Name(id='c', ctx=Load())]))"},
112+
{"a and (b and c)", "eval", "Expression(body=BoolOp(op=And(), values=[Name(id='a', ctx=Load()), BoolOp(op=And(), values=[Name(id='b', ctx=Load()), Name(id='c', ctx=Load())])]))"},
113+
{"a+b-c/d", "eval", "Expression(body=BinOp(left=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Name(id='b', ctx=Load())), op=Sub(), right=BinOp(left=Name(id='c', ctx=Load()), op=Div(), right=Name(id='d', ctx=Load()))))"},
114+
{"a+b-c/d//e", "eval", "Expression(body=BinOp(left=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Name(id='b', ctx=Load())), op=Sub(), right=BinOp(left=BinOp(left=Name(id='c', ctx=Load()), op=Div(), right=Name(id='d', ctx=Load())), op=FloorDiv(), right=Name(id='e', ctx=Load()))))"},
115+
{"a+b-c/d//e%f", "eval", "Expression(body=BinOp(left=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Name(id='b', ctx=Load())), op=Sub(), right=BinOp(left=BinOp(left=BinOp(left=Name(id='c', ctx=Load()), op=Div(), right=Name(id='d', ctx=Load())), op=FloorDiv(), right=Name(id='e', ctx=Load())), op=Mod(), right=Name(id='f', ctx=Load()))))"},
116+
{"a+b-c/d//e%f**g", "eval", "Expression(body=BinOp(left=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Name(id='b', ctx=Load())), op=Sub(), right=BinOp(left=BinOp(left=BinOp(left=Name(id='c', ctx=Load()), op=Div(), right=Name(id='d', ctx=Load())), op=FloorDiv(), right=Name(id='e', ctx=Load())), op=Mod(), right=BinOp(left=Name(id='f', ctx=Load()), op=Pow(), right=Name(id='g', ctx=Load())))))"},
117+
{"a+b-c/d//e%f**g|h&i^k<<l>>m", "eval", "Expression(body=BinOp(left=BinOp(left=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Name(id='b', ctx=Load())), op=Sub(), right=BinOp(left=BinOp(left=BinOp(left=Name(id='c', ctx=Load()), op=Div(), right=Name(id='d', ctx=Load())), op=FloorDiv(), right=Name(id='e', ctx=Load())), op=Mod(), right=BinOp(left=Name(id='f', ctx=Load()), op=Pow(), right=Name(id='g', ctx=Load())))), op=BitOr(), right=BinOp(left=BinOp(left=Name(id='h', ctx=Load()), op=BitAnd(), right=Name(id='i', ctx=Load())), op=BitXor(), right=BinOp(left=BinOp(left=Name(id='k', ctx=Load()), op=LShift(), right=Name(id='l', ctx=Load())), op=RShift(), right=Name(id='m', ctx=Load())))))"},
118+
{"a==b", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[Eq()], comparators=[Name(id='b', ctx=Load())]))"},
119+
{"a!=b", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[NotEq()], comparators=[Name(id='b', ctx=Load())]))"},
120+
{"a<b", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[Lt()], comparators=[Name(id='b', ctx=Load())]))"},
121+
{"a<=b", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[LtE()], comparators=[Name(id='b', ctx=Load())]))"},
122+
{"a>b", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[Gt()], comparators=[Name(id='b', ctx=Load())]))"},
123+
{"a>=b", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[GtE()], comparators=[Name(id='b', ctx=Load())]))"},
124+
{"a is b", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[Is()], comparators=[Name(id='b', ctx=Load())]))"},
125+
{"a is not b", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[IsNot()], comparators=[Name(id='b', ctx=Load())]))"},
126+
{"a in b", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[In()], comparators=[Name(id='b', ctx=Load())]))"},
127+
{"a not in b", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[NotIn()], comparators=[Name(id='b', ctx=Load())]))"},
128+
{"a<b<c<d", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[Lt(), Lt(), Lt()], comparators=[Name(id='b', ctx=Load()), Name(id='c', ctx=Load()), Name(id='d', ctx=Load())]))"},
129+
{"a==b<c>d", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[Eq(), Lt(), Gt()], comparators=[Name(id='b', ctx=Load()), Name(id='c', ctx=Load()), Name(id='d', ctx=Load())]))"},
130+
{"(a==b)<c", "eval", "Expression(body=Compare(left=Compare(left=Name(id='a', ctx=Load()), ops=[Eq()], comparators=[Name(id='b', ctx=Load())]), ops=[Lt()], comparators=[Name(id='c', ctx=Load())]))"},
131+
{"a==(b<c)", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[Eq()], comparators=[Compare(left=Name(id='b', ctx=Load()), ops=[Lt()], comparators=[Name(id='c', ctx=Load())])]))"},
132+
{"(a==b)<(c>d)>e", "eval", "Expression(body=Compare(left=Compare(left=Name(id='a', ctx=Load()), ops=[Eq()], comparators=[Name(id='b', ctx=Load())]), ops=[Lt(), Gt()], comparators=[Compare(left=Name(id='c', ctx=Load()), ops=[Gt()], comparators=[Name(id='d', ctx=Load())]), Name(id='e', ctx=Load())]))"},
90133
// END TESTS
91134
} {
92135
Ast, err := ParseString(test.in, test.mode)

parser/make_grammar_test.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
("[1,]", "eval"),
4747
("[1,2]", "eval"),
4848
("[1,2,]", "eval"),
49+
4950
("( a for a in ab )", "eval"),
5051
("( a for a, in ab )", "eval"),
5152
("( a for a, b in ab )", "eval"),
@@ -78,6 +79,59 @@
7879
("{ a:b for a in ab for A in AB }", "eval"),
7980
("{ a:b for a in ab if a if b for A in AB if c }", "eval"),
8081

82+
# BinOp
83+
("a|b", "eval"),
84+
("a^b", "eval"),
85+
("a&b", "eval"),
86+
("a<<b", "eval"),
87+
("a>>b", "eval"),
88+
("a+b", "eval"),
89+
("a-b", "eval"),
90+
("a*b", "eval"),
91+
("a/b", "eval"),
92+
("a//b", "eval"),
93+
("a**b", "eval"),
94+
95+
# UnaryOp
96+
("not a", "eval"),
97+
("+a", "eval"),
98+
("-a", "eval"),
99+
("~a", "eval"),
100+
101+
# BoolOp
102+
("a and b", "eval"),
103+
("a or b", "eval"),
104+
("a or b or c", "eval"),
105+
("(a or b) or c", "eval"),
106+
("a or (b or c)", "eval"),
107+
("a and b and c", "eval"),
108+
("(a and b) and c", "eval"),
109+
("a and (b and c)", "eval"),
110+
111+
# Exprs
112+
("a+b-c/d", "eval"),
113+
("a+b-c/d//e", "eval"),
114+
("a+b-c/d//e%f", "eval"),
115+
("a+b-c/d//e%f**g", "eval"),
116+
("a+b-c/d//e%f**g|h&i^k<<l>>m", "eval"),
117+
118+
("a==b", "eval"),
119+
("a!=b", "eval"),
120+
("a<b", "eval"),
121+
("a<=b", "eval"),
122+
("a>b", "eval"),
123+
("a>=b", "eval"),
124+
("a is b", "eval"),
125+
("a is not b", "eval"),
126+
("a in b", "eval"),
127+
("a not in b", "eval"),
128+
129+
("a<b<c<d", "eval"),
130+
("a==b<c>d", "eval"),
131+
("(a==b)<c", "eval"),
132+
("a==(b<c)", "eval"),
133+
("(a==b)<(c>d)>e", "eval"),
134+
81135
# ("del a,b", "exec"),
82136
]
83137

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy