Repository: go-python/gpython (go)

Issue:
SyntaxError of global declaration don't stop program
```python
a = 3
global a
print(a)

b = 2 + 5
print(b)
```
This code generate syntax error, but gpython doesn't stop program

### Expected Result
```bash
Hyeockz:bin hyeockjinkim$ python3 g.py 
  File "g.py", line 2
    global a
SyntaxError: name 'a' is assigned to before global declaration
```

### Actual Result
```bash
2019/09/09 00:08:36 name 'a' is assigned to before global declaration
3
7
```
SyntaxError in python3 is Error, not warning. So I think it should be modified.

Pull request:
Generate SyntaxError of global declaration
Generate SyntaxError instead of SyntaxWarning
if global declaration is for priviously used variable

Fixes #72

Patch:
diff --git a/symtable/symtable.go b/symtable/symtable.go
index daf846b..1513f69 100644
--- a/symtable/symtable.go
+++ b/symtable/symtable.go
@@ -17,7 +17,6 @@ package symtable
 
 import (
 	"fmt"
-	"log"
 	"sort"
 	"strings"
 
@@ -229,13 +228,10 @@ func (st *SymTable) Parse(Ast ast.Ast) {
 				cur, ok := st.Symbols[string(name)]
 				if ok {
 					if (cur.Flags & DefLocal) != 0 {
-						// FIXME this should be a warning
-						log.Printf("name '%s' is assigned to before nonlocal declaration", name)
-
+						st.panicSyntaxErrorf(node, "name '%s' is assigned to before nonlocal declaration", name)
 					}
 					if (cur.Flags & DefUse) != 0 {
-						// FIXME this should be a warning
-						log.Printf("name '%s' is used prior to nonlocal declaration", name)
+						st.panicSyntaxErrorf(node, "name '%s' is used prior to nonlocal declaration", name)
 					}
 				}
 				st.AddDef(node, name, DefNonlocal)
@@ -245,13 +241,11 @@ func (st *SymTable) Parse(Ast ast.Ast) {
 				cur, ok := st.Symbols[string(name)]
 				if ok {
 					if (cur.Flags & DefLocal) != 0 {
-						// FIXME this should be a warning
-						log.Printf("name '%s' is assigned to before global declaration", name)
+						st.panicSyntaxErrorf(node, "name '%s' is assigned to before global declaration", name)
 
 					}
 					if (cur.Flags & DefUse) != 0 {
-						// FIXME this should be a warning
-						log.Printf("name '%s' is used prior to global declaration", name)
+						st.panicSyntaxErrorf(node, "name '%s' is used prior to global declaration", name)
 					}
 				}
 				st.AddDef(node, name, DefGlobal)


Test patch:
diff --git a/symtable/symtable_data_test.go b/symtable/symtable_data_test.go
index a09e5d8..05ec1da 100644
--- a/symtable/symtable_data_test.go
+++ b/symtable/symtable_data_test.go
@@ -514,7 +514,7 @@ var symtableTestData = []struct {
 				Children: Children{},
 			},
 		},
-	}, nil, ""},
+	}, nil,""},
 	{"def fn(a):\n    global b\n    global b\n    return b", "exec", &SymTable{
 		Type:              ModuleBlock,
 		Name:              "top",
@@ -568,112 +568,8 @@ var symtableTestData = []struct {
 			},
 		},
 	}, nil, ""},
-	{"def inner():\n  print(x)\n  global x\n", "exec", &SymTable{
-		Type:              ModuleBlock,
-		Name:              "top",
-		Lineno:            0,
-		Unoptimized:       optTopLevel,
-		Nested:            false,
-		Free:              false,
-		ChildFree:         false,
-		Generator:         false,
-		Varargs:           false,
-		Varkeywords:       false,
-		ReturnsValue:      false,
-		NeedsClassClosure: false,
-		Varnames:          []string{},
-		Symbols: Symbols{
-			"inner": Symbol{
-				Flags: DefLocal,
-				Scope: ScopeLocal,
-			},
-			"x": Symbol{
-				Flags: DefGlobal,
-				Scope: ScopeGlobalExplicit,
-			},
-		},
-		Children: Children{
-			&SymTable{
-				Type:              FunctionBlock,
-				Name:              "inner",
-				Lineno:            1,
-				Unoptimized:       0,
-				Nested:            false,
-				Free:              false,
-				ChildFree:         false,
-				Generator:         false,
-				Varargs:           false,
-				Varkeywords:       false,
-				ReturnsValue:      false,
-				NeedsClassClosure: false,
-				Varnames:          []string{},
-				Symbols: Symbols{
-					"print": Symbol{
-						Flags: DefUse,
-						Scope: ScopeGlobalImplicit,
-					},
-					"x": Symbol{
-						Flags: DefGlobal | DefUse,
-						Scope: ScopeGlobalExplicit,
-					},
-				},
-				Children: Children{},
-			},
-		},
-	}, nil, ""},
-	{"def fn(a):\n    b = 6\n    global b\n    b = a", "exec", &SymTable{
-		Type:              ModuleBlock,
-		Name:              "top",
-		Lineno:            0,
-		Unoptimized:       optTopLevel,
-		Nested:            false,
-		Free:              false,
-		ChildFree:         false,
-		Generator:         false,
-		Varargs:           false,
-		Varkeywords:       false,
-		ReturnsValue:      false,
-		NeedsClassClosure: false,
-		Varnames:          []string{},
-		Symbols: Symbols{
-			"b": Symbol{
-				Flags: DefGlobal,
-				Scope: ScopeGlobalExplicit,
-			},
-			"fn": Symbol{
-				Flags: DefLocal,
-				Scope: ScopeLocal,
-			},
-		},
-		Children: Children{
-			&SymTable{
-				Type:              FunctionBlock,
-				Name:              "fn",
-				Lineno:            1,
-				Unoptimized:       0,
-				Nested:            false,
-				Free:              false,
-				ChildFree:         false,
-				Generator:         false,
-				Varargs:           false,
-				Varkeywords:       false,
-				ReturnsValue:      false,
-				NeedsClassClosure: false,
-				Varnames:          []string{"a"},
-				Symbols: Symbols{
-					"a": Symbol{
-						Flags: DefParam | DefUse,
-						Scope: ScopeLocal,
-					},
-					"b": Symbol{
-						Flags: DefGlobal | DefLocal,
-						Scope: ScopeGlobalExplicit,
-					},
-				},
-				Children: Children{},
-			},
-		},
-	}, nil, ""},
+	{"def inner():\n  print(x)\n  global x\n", "exec", nil, py.SyntaxError, "name 'x' is used prior to global declaration"},
+	{"def fn(a):\n    b = 6\n    global b\n    b = a", "exec", nil, py.SyntaxError, "name 'b' is assigned to before global declaration"},
 	{"def fn(a=b,c=1):\n    return a+b", "exec", &SymTable{
 		Type:              ModuleBlock,
 		Name:              "top",
@@ -817,154 +713,8 @@ var symtableTestData = []struct {
 	}, nil, ""},
 	{"def fn(a):\n    nonlocal b\n    ", "exec", nil, py.SyntaxError, "no binding for nonlocal 'b' found"},
 	{"def outer():\n   def inner():\n       nonlocal x\n       x = 2", "exec", nil, py.SyntaxError, "no binding for nonlocal 'x' found"},
-	{"def outer():\n   x = 1\n   def inner():\n       print(x)\n       nonlocal x\n", "exec", &SymTable{
-		Type:              ModuleBlock,
-		Name:              "top",
-		Lineno:            0,
-		Unoptimized:       optTopLevel,
-		Nested:            false,
-		Free:              false,
-		ChildFree:         true,
-		Generator:         false,
-		Varargs:           false,
-		Varkeywords:       false,
-		ReturnsValue:      false,
-		NeedsClassClosure: false,
-		Varnames:          []string{},
-		Symbols: Symbols{
-			"outer": Symbol{
-				Flags: DefLocal,
-				Scope: ScopeLocal,
-			},
-		},
-		Children: Children{
-			&SymTable{
-				Type:              FunctionBlock,
-				Name:              "outer",
-				Lineno:            1,
-				Unoptimized:       0,
-				Nested:            false,
-				Free:              false,
-				ChildFree:         true,
-				Generator:         false,
-				Varargs:           false,
-				Varkeywords:       false,
-				ReturnsValue:      false,
-				NeedsClassClosure: false,
-				Varnames:          []string{},
-				Symbols: Symbols{
-					"inner": Symbol{
-						Flags: DefLocal,
-						Scope: ScopeLocal,
-					},
-					"x": Symbol{
-						Flags: DefLocal,
-						Scope: ScopeCell,
-					},
-				},
-				Children: Children{
-					&SymTable{
-						Type:              FunctionBlock,
-						Name:              "inner",
-						Lineno:            3,
-						Unoptimized:       0,
-						Nested:            true,
-						Free:              true,
-						ChildFree:         false,
-						Generator:         false,
-						Varargs:           false,
-						Varkeywords:       false,
-						ReturnsValue:      false,
-						NeedsClassClosure: false,
-						Varnames:          []string{},
-						Symbols: Symbols{
-							"print": Symbol{
-								Flags: DefUse,
-								Scope: ScopeGlobalImplicit,
-							},
-							"x": Symbol{
-								Flags: DefNonlocal | DefUse,
-								Scope: ScopeFree,
-							},
-						},
-						Children: Children{},
-					},
-				},
-			},
-		},
-	}, nil, ""},
-	{"def outer():\n   x = 1\n   def inner():\n       x = 2\n       nonlocal x", "exec", &SymTable{
-		Type:              ModuleBlock,
-		Name:              "top",
-		Lineno:            0,
-		Unoptimized:       optTopLevel,
-		Nested:            false,
-		Free:              false,
-		ChildFree:         true,
-		Generator:         false,
-		Varargs:           false,
-		Varkeywords:       false,
-		ReturnsValue:      false,
-		NeedsClassClosure: false,
-		Varnames:          []string{},
-		Symbols: Symbols{
-			"outer": Symbol{
-				Flags: DefLocal,
-				Scope: ScopeLocal,
-			},
-		},
-		Children: Children{
-			&SymTable{
-				Type:              FunctionBlock,
-				Name:              "outer",
-				Lineno:            1,
-				Unoptimized:       0,
-				Nested:            false,
-				Free:              false,
-				ChildFree:         true,
-				Generator:         false,
-				Varargs:           false,
-				Varkeywords:       false,
-				ReturnsValue:      false,
-				NeedsClassClosure: false,
-				Varnames:          []string{},
-				Symbols: Symbols{
-					"inner": Symbol{
-						Flags: DefLocal,
-						Scope: ScopeLocal,
-					},
-					"x": Symbol{
-						Flags: DefLocal,
-						Scope: ScopeCell,
-					},
-				},
-				Children: Children{
-					&SymTable{
-						Type:              FunctionBlock,
-						Name:              "inner",
-						Lineno:            3,
-						Unoptimized:       0,
-						Nested:            true,
-						Free:              true,
-						ChildFree:         false,
-						Generator:         false,
-						Varargs:           false,
-						Varkeywords:       false,
-						ReturnsValue:      false,
-						NeedsClassClosure: false,
-						Varnames:          []string{},
-						Symbols: Symbols{
-							"x": Symbol{
-								Flags: DefLocal | DefNonlocal,
-								Scope: ScopeFree,
-							},
-						},
-						Children: Children{},
-					},
-				},
-			},
-		},
-	}, nil, ""},
+	{"def outer():\n   x = 1\n   def inner():\n       print(x)\n       nonlocal x\n", "exec", nil, py.SyntaxError, "name 'x' is used prior to nonlocal declaration"},
+	{"def outer():\n   x = 1\n   def inner():\n       x = 2\n       nonlocal x", "exec", nil, py.SyntaxError, "name 'x' is assigned to before nonlocal declaration"},
 	{"def outer():\n   x = 1\n   def inner(x):\n       nonlocal x", "exec", nil, py.SyntaxError, "name 'x' is parameter and nonlocal"},
 	{"def outer():\n   x = 1\n   def inner(x):\n       global x", "exec", nil, py.SyntaxError, "name 'x' is parameter and global"},
 	{"def outer():\n   def inner():\n       global x\n       nonlocal x\n       ", "exec", nil, py.SyntaxError, "name 'x' is nonlocal and global"},