6 new revisions:
Revision: c188d3de5a
Author: Scott Lawrence <
byt...@gmail.com>
Date: Wed Aug 18 11:24:30 2010
Log: removed testing/results directory
http://code.google.com/p/gogc/source/detail?r=c188d3de5a
Revision: 6da93e3ad7
Author: Scott Lawrence <
byt...@gmail.com>
Date: Wed Aug 18 11:25:20 2010
Log: removed testing/ directory (needs redoing)
http://code.google.com/p/gogc/source/detail?r=6da93e3ad7
Revision: 7b2b6ce070
Author: Scott Lawrence <
byt...@gmail.com>
Date: Wed Aug 18 11:27:37 2010
Log: moved docs/latex to docs/paper/latex
http://code.google.com/p/gogc/source/detail?r=7b2b6ce070
Revision: 9544ab0b9d
Author: Scott Lawrence <
byt...@gmail.com>
Date: Fri Aug 20 11:56:45 2010
Log: on the way to a gomake-based build process
http://code.google.com/p/gogc/source/detail?r=9544ab0b9d
Revision: b0d4dfb141
Author: Scott Lawrence <
byt...@gmail.com>
Date: Fri Aug 20 12:05:04 2010
Log: partial top-level Makefiles
http://code.google.com/p/gogc/source/detail?r=b0d4dfb141
Revision: 10477faa93
Author: Scott Lawrence <
byt...@gmail.com>
Date: Fri Aug 20 14:01:45 2010
Log: added header comment to AUTHORS
http://code.google.com/p/gogc/source/detail?r=10477faa93
==============================================================================
Revision: c188d3de5a
Author: Scott Lawrence <
byt...@gmail.com>
Date: Wed Aug 18 11:24:30 2010
Log: removed testing/results directory
http://code.google.com/p/gogc/source/detail?r=c188d3de5a
Deleted:
/testing/results/2010-03-21_fail.go
/testing/results/2010-03-21_gogo_fail.go
/testing/results/2010-03-21_large_number.go
/testing/results/2010-03-21_parse_fail1.go
/testing/results/2010-03-21_scanner_fail_semicolon.go
/testing/results/2010-03-21_token.go
/testing/results/2010-04-11_parse_imports_fail.go
/testing/results/2010-04-11_struct1.go
/testing/results/2010-04-11_struct2.go
/testing/results/2010-04-11_struct3_fail.go
/testing/results/2010-04-11_struct4_fail.go
/testing/results/2010-04-11_struct5_fail.go
/testing/results/2010-04-11_struct6_fail.go
/testing/results/2010-04-11_struct7.go
/testing/results/2010-04-11_vardecl1.go
/testing/results/2010-04-11_vardecl2.go
/testing/results/2010-05-09_struct8_fail.go
/testing/results/2010-05-09_struct9.go
/testing/results/2010-05-09_symtable_fail.go
/testing/results/_gogo_.sog
/testing/results/test.go
=======================================
--- /testing/results/2010-03-21_fail.go Sat May 15 03:29:34 2010
+++ /dev/null
@@ -1,1 +0,0 @@
-tests/2010-03-21_fail.go:9:12: syntax error: Unknown char '%'.
=======================================
--- /testing/results/2010-03-21_gogo_fail.go Sat May 15 03:29:34 2010
+++ /dev/null
@@ -1,1 +0,0 @@
-tests/2010-03-21_gogo_fail.go:15:9: syntax error: unexpected token '(',
expecting one of: {
=======================================
--- /testing/results/2010-03-21_parse_fail1.go Sat May 15 03:29:34 2010
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/2010-03-21_parse_fail1.go:2:6: syntax error: unexpected
token 'func', expecting one of: package
-tests/2010-03-21_parse_fail1.go:2:6: syntax error: unexpected
token 'func', expecting one of: <identifier> (value: func)
=======================================
--- /testing/results/2010-03-21_scanner_fail_semicolon.go Sat May 15
03:29:34 2010
+++ /dev/null
@@ -1,6 +0,0 @@
-tests/2010-03-21_scanner_fail_semicolon.go:42:6: syntax error: unexpected
token '}', expecting one of: ;
-tests/2010-03-21_scanner_fail_semicolon.go:102:46: syntax error:
unexpected token '!=', expecting one of: {
-tests/2010-03-21_scanner_fail_semicolon.go:350:34: syntax error:
unexpected token '(', expecting one of: {
-tests/2010-03-21_scanner_fail_semicolon.go:392:47: syntax error:
unexpected token '==', expecting one of: {
-tests/2010-03-21_scanner_fail_semicolon.go:411:22: syntax error:
unexpected token '(', expecting one of: ;
-tests/2010-03-21_scanner_fail_semicolon.go:417:19: syntax error:
unexpected token '+', expecting one of: }
=======================================
--- /testing/results/2010-03-21_token.go Sat May 15 03:29:34 2010
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/2010-03-21_token.go:10:7: syntax error: unexpected token 'const',
expecting one of: <END-OF-SCAN>
-tests/2010-03-21_token.go:121:6: syntax error: unexpected token '}',
expecting one of: ;
=======================================
--- /testing/results/2010-04-11_parse_imports_fail.go Sat May 15 03:29:34
2010
+++ /dev/null
@@ -1,1 +0,0 @@
-tests/2010-04-11_parse_imports_fail.go:11:1: syntax error: unexpected
token '<identifier> (value: this_is_not_a_string)', expecting one of:
<string> (value: this_is_not_a_string)
=======================================
--- /testing/results/2010-04-11_struct3_fail.go Sat May 15 03:29:34 2010
+++ /dev/null
@@ -1,3 +0,0 @@
-tests/2010-04-11_struct3_fail.go:9:16: syntax error: unexpected
token '<identifier> (value: someArray2)', expecting one of: ;
-tests/2010-04-11_struct3_fail.go:10:16: syntax error: unexpected
token '<identifier> (value: someString)', expecting one of: ;
-tests/2010-04-11_struct3_fail.go:11:2: syntax error: unexpected token '}',
expecting one of: ;
=======================================
--- /testing/results/2010-04-11_struct4_fail.go Sat May 15 03:29:34 2010
+++ /dev/null
@@ -1,1 +0,0 @@
-tests/2010-04-11_struct4_fail.go:7:13: syntax error: unexpected token '{',
expecting one of: struct
=======================================
--- /testing/results/2010-04-11_struct5_fail.go Sat May 15 03:29:34 2010
+++ /dev/null
@@ -1,1 +0,0 @@
-tests/2010-04-11_struct5_fail.go:12:2: syntax error: unexpected
token '<END-OF-SCAN>', expecting one of: ;
=======================================
--- /testing/results/2010-04-11_struct6_fail.go Sat May 15 03:29:34 2010
+++ /dev/null
@@ -1,1 +0,0 @@
-tests/2010-04-11_struct6_fail.go:7:13: syntax error: unexpected
token 'struct', expecting one of: <identifier> (value: struct)
=======================================
--- /testing/results/_gogo_.sog Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,595 +0,0 @@
-//
-// --------------------
-// GoGC compiler output
-// --------------------
-//
-
-// Syntax: Plan-9 assembler
-//
-// This code is automatically generated. DO NOT EDIT IT!
-//
-
-__UNLINKED_CODE
-//Symbol table:
-//TYPE,0,·uint64,8,8
-//TYPE,0,·byte,1,8
-//TYPE,0,·string,16,16
-//TYPE,0,·bool,8,8
-//TYPE,0,main·foo,32,32
-//TYPE,0,main·test,360,360
-//FUNC,0,main·init
-//FUNC,0,main·test,bla:·uint64,blub:·string
-//FUNC,0,main·foo,return value:·uint64
-//FUNC,0,main·bar,a:·uint64,return value:·uint64
-//FUNC,0,main·foobar,a:·uint64,b:·uint64,c:·uint64,return value:·uint64
-//FUNC,0,main·bazz,a:·uint64,return value:·uint64
-//FUNC,0,main·blub,r:·string,return value:·string
-//FUNC,0,main·main
-//FUNC,0,main·bazz_fwd,b:·byte,return value:·uint64
-//FUNC,0,main·foo_fwd
-//FUNC,0,main·muh
-//FUNC,0,main·maeh,y:·string,z:·string,return value:·string
-//End Symbol table
-
-//--- String buffer start ('Test') at tests/test.go:24:26
-DATA data+712(SB)/1, $84
-DATA data+713(SB)/1, $101
-DATA data+714(SB)/1, $115
-DATA data+715(SB)/1, $116
-DATA data+716(SB)/1, $0
-//--- String buffer end at tests/test.go:24:26
-//--- String buffer start ('ABC') at tests/test.go:78:25
-DATA data+736(SB)/1, $65
-DATA data+737(SB)/1, $66
-DATA data+738(SB)/1, $67
-DATA data+739(SB)/1, $0
-//--- String buffer end at tests/test.go:78:25
-GLOBL data(SB),$760
-
-TEXT main·init(SB),0,$0-0
- //--- Global variable assignment start at tests/test.go:15:21
- //--- Global variable assignment RHS load start at tests/test.go:15:21
- //--- Global variable assignment RHS load end at tests/test.go:15:31
- MOVB $7, data+8(SB)
- //--- Global variable assignment end at tests/test.go:15:31
- //--- Global variable assignment start at tests/test.go:16:24
- //--- Global variable assignment RHS load start at tests/test.go:16:24
- ANDQ $255, R8
- MOVB data+8(SB), R8
- ANDQ $255, R8
- ADDB $1, R8
- //--- Global variable assignment RHS load end at tests/test.go:16:37
- MOVQ R8, data+16(SB)
- //--- Global variable assignment end at tests/test.go:16:37
- //--- Assign byte buffer to new string constant start at
tests/test.go:24:26
- LEAQ data+712(SB), R8
- MOVQ R8, data+720(SB)
- //--- Assign byte buffer to new string constant end at
tests/test.go:24:26
- //--- Assign string length to new string constant start at
tests/test.go:24:26
- MOVQ $4, data+728(SB)
- //--- Assign string length to new string constant end at
tests/test.go:24:26
- //--- Assign byte buffer to new string constant start at
tests/test.go:78:25
- LEAQ data+736(SB), R8
- MOVQ R8, data+744(SB)
- //--- Assign byte buffer to new string constant end at
tests/test.go:78:25
- //--- Assign string length to new string constant start at
tests/test.go:78:25
- MOVQ $3, data+752(SB)
- //--- Assign string length to new string constant end at
tests/test.go:78:25
- RET
-
-TEXT main·test(SB),0,$0-0
- //--- Local variable assignment start at tests/test.go:22:20
- //--- Local variable assignment RHS load start at tests/test.go:22:20
- //--- Local variable assignment RHS load end at tests/test.go:22:22
- MOVQ $5, -8(SP)
- //--- Local variable assignment end at tests/test.go:22:22
- //--- Local variable assignment start at tests/test.go:23:20
- //--- Local variable assignment RHS load start at tests/test.go:23:20
- //--- Local variable assignment RHS load end at tests/test.go:23:22
- MOVQ $1, -16(SP)
- //--- Local variable assignment end at tests/test.go:23:22
- //--- Local variable assignment start at tests/test.go:24:20
- //--- Local variable assignment RHS load start at tests/test.go:24:20
- //--- Local variable assignment RHS load end at tests/test.go:24:27
- MOVQ data+720(SB), R8
- MOVQ data+728(SB), R9
- MOVQ R8, -32(SP)
- MOVQ R9, -24(SP)
- //--- Local variable assignment end at tests/test.go:24:27
- //--- Assignment start at tests/test.go:28:9
- //--- Assignment LHS load start at tests/test.go:28:9
- //--- Assignment LHS load end at tests/test.go:28:9
- //--- Assignment RHS load start at tests/test.go:28:12
- ANDQ $255, R8
- MOVB -48(SP), R8
- ANDQ $255, R8
- ADDB -56(SP), R8
- ANDQ $255, R8
- ADDB $1, R8
- SUBQ -8(SP), R8
- //--- Assignment RHS load end at tests/test.go:28:23
- MOVQ R8, -16(SP)
- //--- Assignment end at tests/test.go:28:23
- //--- Assignment start at tests/test.go:29:9
- //--- Assignment LHS load start at tests/test.go:29:9
- //--- Assignment LHS load end at tests/test.go:29:9
- //--- Assignment RHS load start at tests/test.go:29:11
- MOVQ -16(SP), AX
- MOVQ -8(SP), R8
- MULQ R8
- MOVQ AX, R8
- ANDQ $255, R9
- MOVB $1, R9
- ADDQ R8, R9
- //--- Assignment RHS load end at tests/test.go:29:19
- MOVQ R9, -8(SP)
- //--- Assignment end at tests/test.go:29:19
- //--- Assignment start at tests/test.go:30:9
- //--- Assignment LHS load start at tests/test.go:30:9
- //--- Assignment LHS load end at tests/test.go:30:9
- //--- Assignment RHS load start at tests/test.go:30:20
- MOVQ -8(SP), AX
- MOVQ $32, R8
- MULQ R8
- MOVQ AX, R8
- LEAQ data+24(SB), R9
- ADDQ R8, R9
- ADDQ $8, R9
- //--- Assignment RHS load end at tests/test.go:30:28
- MOVQ R9, BX
- MOVQ (BX), R9
- MOVQ 8(BX), R8
- MOVQ R9, -32(SP)
- MOVQ R8, -24(SP)
- //--- Assignment end at tests/test.go:30:28
- //--- Assignment start at tests/test.go:31:7
- //--- Assignment LHS load start at tests/test.go:31:7
- MOVQ -32(SP), R8
- ADDQ $1, R8
- //--- Assignment LHS load end at tests/test.go:31:12
- //--- Assignment RHS load start at tests/test.go:31:27
- MOVQ data+704(SB), R9
- ADDQ $352, R9
- MOVQ (R9), R9
- ADDQ $8, R9
- MOVQ (R9), R9
- ADDQ $1, R9
- //--- Assignment RHS load end at tests/test.go:31:35
- MOVB (R9), R9
- ANDQ $255, R9
- MOVB R9, (R8)
- //--- Assignment end at tests/test.go:31:35
- //--- Assignment start at tests/test.go:32:7
- //--- Assignment LHS load start at tests/test.go:32:7
- MOVQ -40(SP), R8
- MOVQ (R8), R8
- ADDQ $2, R8
- //--- Assignment LHS load end at tests/test.go:32:12
- //--- Assignment RHS load start at tests/test.go:32:15
- //--- Assignment RHS load end at tests/test.go:32:16
- MOVB $120, (R8)
- //--- Assignment end at tests/test.go:32:16
- //--- Assignment start at tests/test.go:33:9
- //--- Assignment LHS load start at tests/test.go:33:9
- //--- Assignment LHS load end at tests/test.go:33:9
- //--- Assignment RHS load start at tests/test.go:33:20
- MOVQ -16(SP), AX
- MOVQ $32, R8
- MULQ R8
- MOVQ AX, R8
- LEAQ data+24(SB), R9
- ADDQ R8, R9
- //--- Addition/subtraction by zero omitted at tests/test.go:33:28
- MOVQ data+696(SB), R8
- //--- Addition/subtraction by zero omitted at tests/test.go:33:51
- MOVQ (R9), R9
- MOVQ (R8), R8
- ADDQ R8, R9
- //--- Assignment RHS load end at tests/test.go:33:51
- MOVQ R9, -8(SP)
- //--- Assignment end at tests/test.go:33:51
- //--- Assignment start at tests/test.go:34:16
- //--- Assignment LHS load start at tests/test.go:34:16
- //--- Assignment LHS load end at tests/test.go:34:26
- //--- Assignment RHS load start at tests/test.go:34:28
- //--- Assignment RHS load end at tests/test.go:34:29
- LEAQ -8(SP), R8
- MOVQ R8, data+48(SB)
- //--- Assignment end at tests/test.go:34:29
- //--- Assignment start at tests/test.go:35:16
- //--- Assignment LHS load start at tests/test.go:35:16
- //--- Assignment LHS load end at tests/test.go:35:26
- //--- Assignment RHS load start at tests/test.go:35:41
- MOVQ data+704(SB), R8
- ADDQ $352, R8
- MOVQ (R8), R8
- ADDQ $24, R8
- //--- Assignment RHS load end at tests/test.go:35:46
- MOVQ (R8), R8
- MOVQ R8, data+48(SB)
- //--- Assignment end at tests/test.go:35:46
- //--- Assignment start at tests/test.go:36:16
- //--- Assignment LHS load start at tests/test.go:36:16
- MOVQ -8(SP), AX
- MOVQ $32, R8
- MULQ R8
- MOVQ AX, R8
- LEAQ data+24(SB), R9
- ADDQ R8, R9
- ADDQ $24, R9
- //--- Assignment LHS load end at tests/test.go:36:26
- //--- Assignment RHS load start at tests/test.go:36:28
- //--- Assignment RHS load end at tests/test.go:36:29
- LEAQ -8(SP), R8
- MOVQ R8, (R9)
- //--- Assignment end at tests/test.go:36:29
- //--- Assignment start at tests/test.go:37:16
- //--- Assignment LHS load start at tests/test.go:37:16
- MOVQ -8(SP), AX
- MOVQ $32, R8
- MULQ R8
- MOVQ AX, R8
- LEAQ data+24(SB), R9
- ADDQ R8, R9
- ADDQ $24, R9
- //--- Assignment LHS load end at tests/test.go:37:26
- //--- Assignment RHS load start at tests/test.go:37:41
- MOVQ data+704(SB), R8
- ADDQ $352, R8
- MOVQ (R8), R8
- ADDQ $24, R8
- //--- Assignment RHS load end at tests/test.go:37:46
- MOVQ (R8), R8
- MOVQ R8, (R9)
- //--- Assignment end at tests/test.go:37:46
- //--- If start at tests/test.go:39:8
- CMPQ -8(SP), $10
- JGE IF_tests_test_39_1_END
- CMPQ -16(SP), $10
- JG IF_tests_test_39_2_END
-IF_tests_test_39_1_END:
- CMPQ -8(SP), $5
- JE IF_tests_test_39_2_END
- JMP IF_tests_test_39_END
-IF_tests_test_39_2_END:
- //--- If start at tests/test.go:40:12
- CMPQ -16(SP), $15
- JG IF_tests_test_40_1_END
- JMP IF_tests_test_40_END
-IF_tests_test_40_1_END:
- //--- Assignment start at tests/test.go:41:17
- //--- Assignment LHS load start at tests/test.go:41:17
- //--- Assignment LHS load end at tests/test.go:41:17
- //--- Assignment RHS load start at tests/test.go:41:19
- //--- Assignment RHS load end at tests/test.go:41:19
- MOVQ $4, -16(SP)
- //--- Assignment end at tests/test.go:41:19
- JMP IF_tests_test_40_ELSE_END
-IF_tests_test_40_END:
- //--- Else start at tests/test.go:42:16
- //--- Assignment start at tests/test.go:43:17
- //--- Assignment LHS load start at tests/test.go:43:17
- //--- Assignment LHS load end at tests/test.go:43:17
- //--- Assignment RHS load start at tests/test.go:43:19
- //--- Assignment RHS load end at tests/test.go:43:19
- MOVQ $3, -16(SP)
- //--- Assignment end at tests/test.go:43:19
- //--- Else end at tests/test.go:44:10
-IF_tests_test_40_ELSE_END:
- JMP IF_tests_test_39_ELSE_END
-IF_tests_test_39_END:
- //--- Else start at tests/test.go:45:12
- //--- Assignment start at tests/test.go:46:13
- //--- Assignment LHS load start at tests/test.go:46:13
- //--- Assignment LHS load end at tests/test.go:46:13
- //--- Assignment RHS load start at tests/test.go:46:15
- //--- Assignment RHS load end at tests/test.go:46:15
- MOVQ $2, -16(SP)
- //--- Assignment end at tests/test.go:46:15
- //--- Else end at tests/test.go:47:6
-IF_tests_test_39_ELSE_END:
- RET
-
-TEXT main·foo(SB),0,$0-0
- //--- Return value assignment start at tests/test.go:51:12
- //--- Return expression load start at tests/test.go:51:12
- //--- Return expression load end at tests/test.go:51:14
- MOVQ $3, 8(SP)
- //--- Return value assignment end at tests/test.go:51:14
- RET
-
-TEXT main·bar(SB),0,$0-0
- //--- Return value assignment start at tests/test.go:55:12
- //--- Return expression load start at tests/test.go:55:12
- //--- Return expression load end at tests/test.go:55:14
- MOVQ 8(SP), R8
- MOVQ R8, 16(SP)
- //--- Return value assignment end at tests/test.go:55:14
- RET
-
-TEXT main·foobar(SB),0,$0-0
- //--- Return value assignment start at tests/test.go:59:12
- //--- Return expression load start at tests/test.go:59:12
- MOVQ 8(SP), R8
- ADDQ 16(SP), R8
- ADDQ 24(SP), R8
- //--- Return expression load end at tests/test.go:59:22
- MOVQ R8, 32(SP)
- //--- Return value assignment end at tests/test.go:59:22
- RET
-
-TEXT main·bazz(SB),0,$0-0
- //--- Local variable assignment start at tests/test.go:64:22
- //--- Local variable assignment RHS load start at tests/test.go:64:22
- //--- Local variable assignment RHS load end at tests/test.go:64:24
- MOVQ $3, -16(SP)
- //--- Local variable assignment end at tests/test.go:64:24
- //--- Saving registers before function call start at tests/test.go:65:10
- //--- Saving registers before function call end at tests/test.go:65:10
- //--- Stack pointer offset before function call for local variables
start at tests/test.go:65:10
- SUBQ $24, SP
- //--- Stack pointer offset before function call for local variables end
at tests/test.go:65:10
- CALL main·foo(SB)
- //--- Stack pointer offset after function call for local variables start
at tests/test.go:65:10
- ADDQ $24, SP
- //--- Stack pointer offset after function call for local variables end
at tests/test.go:65:10
- //--- Restoring registers after function call start at
tests/test.go:65:10
- //--- Restoring registers after function call end at tests/test.go:65:10
- //--- Assignment start at tests/test.go:66:11
- //--- Assignment LHS load start at tests/test.go:66:11
- //--- Assignment LHS load end at tests/test.go:66:11
- //--- Saving registers before function call start at tests/test.go:66:19
- //--- Saving registers before function call end at tests/test.go:66:19
- //--- First parameter expression start at tests/test.go:66:19
- //--- First parameter expression load start at tests/test.go:66:19
- //--- First parameter expression load end at tests/test.go:66:19
- MOVQ -16(SP), R8
- MOVQ R8, -32(SP)
- //--- First parameter expression end at tests/test.go:66:19
- //--- Stack pointer offset before function call for local variables
start at tests/test.go:66:19
- SUBQ $32, SP
- //--- Stack pointer offset before function call for local variables end
at tests/test.go:66:19
- CALL main·bar(SB)
- //--- Stack pointer offset after function call for local variables start
at tests/test.go:66:19
- ADDQ $32, SP
- //--- Stack pointer offset after function call for local variables end
at tests/test.go:66:19
- //--- Restoring registers after function call start at
tests/test.go:66:19
- //--- Restoring registers after function call end at tests/test.go:66:19
- MOVQ -24(SP), R8
- MOVQ R8, -16(SP)
- //--- Assignment end at tests/test.go:66:20
- //--- Assignment start at tests/test.go:67:11
- //--- Assignment LHS load start at tests/test.go:67:11
- //--- Assignment LHS load end at tests/test.go:67:11
- //--- Saving registers before function call start at tests/test.go:67:20
- //--- Saving registers before function call end at tests/test.go:67:20
- //--- First parameter expression start at tests/test.go:67:20
- //--- First parameter expression load start at tests/test.go:67:20
- //--- First parameter expression load end at tests/test.go:67:20
- MOVQ 8(SP), R8
- MOVQ R8, -48(SP)
- //--- First parameter expression end at tests/test.go:67:20
- //--- Subsequent parameter expression start at tests/test.go:67:20
- //--- Subsequent parameter expression load start at tests/test.go:67:20
- //--- Subsequent parameter expression load end at tests/test.go:67:25
- MOVQ -16(SP), R8
- MOVQ R8, -40(SP)
- //--- Subsequent parameter expression end at tests/test.go:67:25
- //--- Subsequent parameter expression start at tests/test.go:67:25
- //--- Subsequent parameter expression load start at tests/test.go:67:25
- //--- Subsequent parameter expression load end at tests/test.go:67:28
- MOVQ $3, -32(SP)
- //--- Subsequent parameter expression end at tests/test.go:67:28
- //--- Stack pointer offset before function call for local variables
start at tests/test.go:67:28
- SUBQ $48, SP
- //--- Stack pointer offset before function call for local variables end
at tests/test.go:67:28
- CALL main·foobar(SB)
- //--- Stack pointer offset after function call for local variables start
at tests/test.go:67:28
- ADDQ $48, SP
- //--- Stack pointer offset after function call for local variables end
at tests/test.go:67:28
- //--- Restoring registers after function call start at
tests/test.go:67:28
- //--- Restoring registers after function call end at tests/test.go:67:28
- MOVQ -24(SP), R8
- MOVQ R8, -8(SP)
- //--- Assignment end at tests/test.go:67:29
- //--- Return value assignment start at tests/test.go:68:12
- //--- Return expression load start at tests/test.go:68:12
- //--- Return expression load end at tests/test.go:68:16
- MOVQ -8(SP), R8
- MOVQ R8, 16(SP)
- //--- Return value assignment end at tests/test.go:68:16
- RET
-
-TEXT main·blub(SB),0,$0-0
- //--- Local variable assignment start at tests/test.go:72:20
- //--- Local variable assignment RHS load start at tests/test.go:72:20
- //--- Local variable assignment RHS load end at tests/test.go:72:22
- MOVQ 8(SP), R8
- MOVQ 16(SP), R9
- MOVQ R8, -16(SP)
- MOVQ R9, -8(SP)
- //--- Local variable assignment end at tests/test.go:72:22
- //--- Return value assignment start at tests/test.go:73:12
- //--- Return expression load start at tests/test.go:73:12
- //--- Return expression load end at tests/test.go:73:14
- MOVQ -16(SP), R8
- MOVQ -8(SP), R9
- MOVQ R8, 24(SP)
- MOVQ R9, 32(SP)
- //--- Return value assignment end at tests/test.go:73:14
- RET
-
-TEXT main·main(SB),0,$0-0
- //--- Local variable assignment start at tests/test.go:78:20
- //--- Local variable assignment RHS load start at tests/test.go:78:20
- //--- Local variable assignment RHS load end at tests/test.go:78:26
- MOVQ data+744(SB), R8
- MOVQ data+752(SB), R9
- MOVQ R8, -24(SP)
- MOVQ R9, -16(SP)
- //--- Local variable assignment end at tests/test.go:78:26
- //--- Assignment start at tests/test.go:80:11
- //--- Assignment LHS load start at tests/test.go:80:11
- //--- Assignment LHS load end at tests/test.go:80:11
- //--- Saving registers before function call start at tests/test.go:80:18
- //--- Saving registers before function call end at tests/test.go:80:18
- //--- First parameter expression start at tests/test.go:80:18
- //--- First parameter expression load start at tests/test.go:80:18
- //--- First parameter expression load end at tests/test.go:80:18
- MOVQ $1, -56(SP)
- //--- First parameter expression end at tests/test.go:80:18
- //--- Stack pointer offset before function call for local variables
start at tests/test.go:80:18
- SUBQ $56, SP
- //--- Stack pointer offset before function call for local variables end
at tests/test.go:80:18
- CALL main·bazz(SB)
- //--- Stack pointer offset after function call for local variables start
at tests/test.go:80:18
- ADDQ $56, SP
- //--- Stack pointer offset after function call for local variables end
at tests/test.go:80:18
- //--- Restoring registers after function call start at
tests/test.go:80:18
- //--- Restoring registers after function call end at tests/test.go:80:18
- MOVQ -48(SP), R8
- MOVQ R8, -8(SP)
- //--- Assignment end at tests/test.go:80:19
- //--- Assignment start at tests/test.go:81:9
- //--- Assignment LHS load start at tests/test.go:81:9
- //--- Assignment LHS load end at tests/test.go:81:9
- //--- Saving registers before function call start at tests/test.go:81:16
- //--- Saving registers before function call end at tests/test.go:81:16
- //--- First parameter expression start at tests/test.go:81:16
- //--- First parameter expression load start at tests/test.go:81:16
- //--- First parameter expression load end at tests/test.go:81:16
- MOVQ -24(SP), R8
- MOVQ -16(SP), R9
- MOVQ R8, -72(SP)
- MOVQ R9, -64(SP)
- //--- First parameter expression end at tests/test.go:81:16
- //--- Stack pointer offset before function call for local variables
start at tests/test.go:81:16
- SUBQ $72, SP
- //--- Stack pointer offset before function call for local variables end
at tests/test.go:81:16
- CALL main·blub(SB)
- //--- Stack pointer offset after function call for local variables start
at tests/test.go:81:16
- ADDQ $72, SP
- //--- Stack pointer offset after function call for local variables end
at tests/test.go:81:16
- //--- Restoring registers after function call start at
tests/test.go:81:16
- //--- Restoring registers after function call end at tests/test.go:81:16
- MOVQ -56(SP), R8
- MOVQ -48(SP), R9
- MOVQ R8, -40(SP)
- MOVQ R9, -32(SP)
- //--- Assignment end at tests/test.go:81:17
- //--- Assignment start at tests/test.go:82:11
- //--- Assignment LHS load start at tests/test.go:82:11
- //--- Assignment LHS load end at tests/test.go:82:11
- //--- Saving registers before function call start at tests/test.go:82:22
- //--- Saving registers before function call end at tests/test.go:82:22
- //--- First parameter expression start at tests/test.go:82:22
- //--- First parameter expression load start at tests/test.go:82:22
- //--- First parameter expression load end at tests/test.go:82:22
- //--- ##1##main·bazz_fwd## at tests/test.go:82:22
- MOVB $1, -100040(SP)
- //--- First parameter expression end at tests/test.go:82:22
- //--- Stack pointer offset before function call for local variables
start at tests/test.go:82:22
- //--- ##2##main·bazz_fwd## at tests/test.go:82:22
- SUBQ $40, SP
- //--- Stack pointer offset before function call for local variables end
at tests/test.go:82:22
- CALL main·bazz_fwd(SB)
- //--- Stack pointer offset after function call for local variables start
at tests/test.go:82:22
- //--- ##2##main·bazz_fwd## at tests/test.go:82:22
- ADDQ $40, SP
- //--- Stack pointer offset after function call for local variables end
at tests/test.go:82:22
- //--- Restoring registers after function call start at
tests/test.go:82:22
- //--- Restoring registers after function call end at tests/test.go:82:22
- //--- ##1##main·bazz_fwd## at tests/test.go:82:22
- MOVQ -100032(SP), R8
- MOVQ R8, -8(SP)
- //--- Assignment end at tests/test.go:82:23
- RET
-
-TEXT main·foo_fwd(SB),0,$0-0
- //--- Assignment start at tests/test.go:87:11
- //--- Assignment LHS load start at tests/test.go:87:11
- //--- Assignment LHS load end at tests/test.go:87:11
- //--- Saving registers before function call start at tests/test.go:87:22
- //--- Saving registers before function call end at tests/test.go:87:22
- //--- First parameter expression start at tests/test.go:87:22
- //--- First parameter expression load start at tests/test.go:87:22
- //--- First parameter expression load end at tests/test.go:87:22
- //--- ##1##main·bazz_fwd## at tests/test.go:87:22
- MOVB $1, -100008(SP)
- //--- First parameter expression end at tests/test.go:87:22
- //--- Stack pointer offset before function call for local variables
start at tests/test.go:87:22
- //--- ##2##main·bazz_fwd## at tests/test.go:87:22
- SUBQ $8, SP
- //--- Stack pointer offset before function call for local variables end
at tests/test.go:87:22
- CALL main·bazz_fwd(SB)
- //--- Stack pointer offset after function call for local variables start
at tests/test.go:87:22
- //--- ##2##main·bazz_fwd## at tests/test.go:87:22
- ADDQ $8, SP
- //--- Stack pointer offset after function call for local variables end
at tests/test.go:87:22
- //--- Restoring registers after function call start at
tests/test.go:87:22
- //--- Restoring registers after function call end at tests/test.go:87:22
- //--- ##1##main·bazz_fwd## at tests/test.go:87:22
- MOVQ -100000(SP), R8
- MOVQ R8, -8(SP)
- //--- Assignment end at tests/test.go:87:23
- RET
-
-TEXT main·bazz_fwd(SB),0,$0-0
- //--- Return value assignment start at tests/test.go:91:12
- //--- Return expression load start at tests/test.go:91:12
- //--- Return expression load end at tests/test.go:91:14
- ANDQ $255, R8
- MOVB 8(SP), R8
- MOVQ R8, 16(SP)
- //--- Return value assignment end at tests/test.go:91:14
- RET
-
-TEXT main·muh(SB),0,$0-0
- //--- Assignment start at tests/test.go:96:9
- //--- Assignment LHS load start at tests/test.go:96:9
- //--- Assignment LHS load end at tests/test.go:96:9
- //--- Saving registers before function call start at tests/test.go:96:16
- //--- Saving registers before function call end at tests/test.go:96:16
- //--- First parameter expression start at tests/test.go:96:16
- //--- First parameter expression load start at tests/test.go:96:16
- //--- First parameter expression load end at tests/test.go:96:16
- MOVQ -16(SP), R8
- MOVQ -8(SP), R9
- //--- ##1##main·maeh## at tests/test.go:96:16
- MOVQ R8, -100016(SP)
- //--- ##1##main·maeh## at tests/test.go:96:16
- MOVQ R9, -100008(SP)
- //--- First parameter expression end at tests/test.go:96:16
- //--- Subsequent parameter expression start at tests/test.go:96:16
- //--- Subsequent parameter expression load start at tests/test.go:96:16
- //--- Subsequent parameter expression load end at tests/test.go:96:19
- MOVQ -16(SP), R8
- MOVQ -8(SP), R9
- //--- ##1##main·maeh## at tests/test.go:96:19
- MOVQ R8, -100000(SP)
- //--- ##1##main·maeh## at tests/test.go:96:19
- MOVQ R9, -99992(SP)
- //--- Subsequent parameter expression end at tests/test.go:96:19
- //--- Stack pointer offset before function call for local variables
start at tests/test.go:96:19
- //--- ##2##main·maeh## at tests/test.go:96:19
- SUBQ $16, SP
- //--- Stack pointer offset before function call for local variables end
at tests/test.go:96:19
- CALL main·maeh(SB)
- //--- Stack pointer offset after function call for local variables start
at tests/test.go:96:19
- //--- ##2##main·maeh## at tests/test.go:96:19
- ADDQ $16, SP
- //--- Stack pointer offset after function call for local variables end
at tests/test.go:96:19
- //--- Restoring registers after function call start at
tests/test.go:96:19
- //--- Restoring registers after function call end at tests/test.go:96:19
- //--- ##1##main·maeh## at tests/test.go:96:19
- MOVQ -99984(SP), R8
- //--- ##1##main·maeh## at tests/test.go:96:19
- MOVQ -99976(SP), R9
- MOVQ R8, -16(SP)
- MOVQ R9, -8(SP)
- //--- Assignment end at tests/test.go:96:20
- RET
-
-TEXT main·maeh(SB),0,$0-0
- RET
-
==============================================================================
Revision: 6da93e3ad7
Author: Scott Lawrence <
byt...@gmail.com>
Date: Wed Aug 18 11:25:20 2010
Log: removed testing/ directory (needs redoing)
http://code.google.com/p/gogc/source/detail?r=6da93e3ad7
Deleted:
/testing/checksums
/testing/tests/2010-03-21_fail.go
/testing/tests/2010-03-21_gogo_fail.go
/testing/tests/2010-03-21_large_number.go
/testing/tests/2010-03-21_parse_fail1.go
/testing/tests/2010-03-21_scanner_fail_semicolon.go
/testing/tests/2010-03-21_token.go
/testing/tests/2010-04-11_parse_imports_fail.go
/testing/tests/2010-04-11_struct1.go
/testing/tests/2010-04-11_struct2.go
/testing/tests/2010-04-11_struct3_fail.go
/testing/tests/2010-04-11_struct4_fail.go
/testing/tests/2010-04-11_struct5_fail.go
/testing/tests/2010-04-11_struct6_fail.go
/testing/tests/2010-04-11_struct7.go
/testing/tests/2010-04-11_vardecl1.go
/testing/tests/2010-04-11_vardecl2.go
/testing/tests/2010-05-09_struct8_fail.go
/testing/tests/2010-05-09_struct9.go
/testing/tests/2010-05-09_symtable_fail.go
/testing/tests/test.go
/testing/testsuite
=======================================
--- /testing/checksums Sun Jun 20 12:27:03 2010
+++ /dev/null
@@ -1,21 +0,0 @@
-6446e9d2d99d099b9c1815a609c4a18ba5b8b91c9dc23490dda39fabbaf6b842
tmp/2010-03-21_fail.go
-94decdf215e88d3310dcab68808b8ab6d31dcfdda004b27323549a90055a4afe
tmp/2010-03-21_gogo_fail.go
-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
tmp/2010-03-21_large_number.go
-729483e59fa1aeacf616abc8806ab4b0f605b6169d128a5fea518b997124a14e
tmp/2010-03-21_parse_fail1.go
-f92637712b738aa72cb2508dc020fdefbee9a29793b2977aadda3c7e12a73b56
tmp/2010-03-21_scanner_fail_semicolon.go
-629a81ba9a4064d63a3c020a1e3c723ce5daaf61c23efa345a73f23d323cee29
tmp/2010-03-21_token.go
-7a34667a952776ebee6ec7b684a5b32461a1ac4e6ebe264c39e0e0e5afcba96d
tmp/2010-04-11_parse_imports_fail.go
-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
tmp/2010-04-11_struct1.go
-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
tmp/2010-04-11_struct2.go
-de36402376dcdbcf259809b4f9168d2ec0bbe8f9a2a7f489987fc575a55aadb5
tmp/2010-04-11_struct3_fail.go
-091069cfd06065696a0372b6a856fddde686abcc762f2a1fd79270541e6e7db3
tmp/2010-04-11_struct4_fail.go
-3d5e461b6347dcc3f46018bf542fc03e36eec4cd3d20993fa3de50a2feea72d1
tmp/2010-04-11_struct5_fail.go
-368b2f36c358fc8915fbdf438863538201a8948580bab450acac5955b3a90da2
tmp/2010-04-11_struct6_fail.go
-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
tmp/2010-04-11_struct7.go
-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
tmp/2010-04-11_vardecl1.go
-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
tmp/2010-04-11_vardecl2.go
-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
tmp/2010-05-09_struct8_fail.go
-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
tmp/2010-05-09_struct9.go
-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
tmp/2010-05-09_symtable_fail.go
-2da5316fd1f34c5bdd4b5ea85c169e4b63c241e7f8ea995ffacb68fb428a3eb1
tmp/_gogo_.sog
-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
tmp/test.go
=======================================
--- /testing/tests/2010-03-21_fail.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package main
-
-func main() {
- var i uint64;
- i = 2 % 3; // not implemented
-}
=======================================
--- /testing/tests/2010-03-21_gogo_fail.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package main
-
-import "fmt"
-import "os"
-import "unsafe"
-import "syscall"
-import "./libgogo/_obj/libgogo"
-
-func main() {
-
- if len(os.Args) != 2 {
- fmt.Printf("Usage: gogo file.go\n");
- return;
- }
-
- var r0 uintptr;
- var e1 uintptr;
- var e int;
- var fd uint64;
- var errno uint64;
- r0, _, e1 = syscall.Syscall(syscall.SYS_OPEN,
uintptr(unsafe.Pointer(syscall.StringBytePtr(os.Args[1]))), 0, 0);
- e = int(e1);
- fd = uint64(r0);
-
- if e == 0 {
- ScannerTest(fd);
- errno = libgogo.FileClose(fd);
- if errno != 0 {
- libgogo.ExitError("Error closing file", errno);
- }
- } else {
- fmt.Printf("Error opening file %s.\n", os.Args[1]);
- }
-}
=======================================
--- /testing/tests/2010-03-21_large_number.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package main
-
-func main() {
- var i uint64;
- i = 18446744073709551615;
-}
=======================================
--- /testing/tests/2010-03-21_parse_fail1.go Sun Mar 21 13:38:26 2010
+++ /dev/null
@@ -1,4 +0,0 @@
-
-func asdf () {
-
-}
=======================================
--- /testing/tests/2010-03-21_scanner_fail_semicolon.go Tue Aug 17 09:58:38
2010
+++ /dev/null
@@ -1,418 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-// This file holds the basic scanning routines that separate a source file
-// into the various tokens
-
-package main
-
-import "./libgogo/_obj/libgogo"
-import "fmt"
-
-// Token struct holding the relevant data of a parsed token.
-type Token struct {
- id uint64; // The id. Is one of TOKEN_*
- intValue uint64; // value storing the integer value if the token is
TOKEN_INTEGER
- strValue string; // Value storing the token string if the token is
TOKEN_STRING or TOKEN_IDENTIFIER
- nextChar byte; // Sometime the next char is already read. It is stored
here to be re-assigned in the next GetNextToken() round
-};
-
-func GetNextTokenRaw(fd uint64, tok *Token) {
- var singleChar byte; // Byte holding the last read value
- // Flag indicating whether we are in a comment.
- // 0 for no comment
- // 1 for a single line comment
- // 2 for a multi line comment
- var inComment uint64;
- var done uint64; // Flag indicating whether a cycle (Token) is finsihed
- var spaceDone uint64; // Flag indicating whether an abolishment cycle
is finished
-
- // Initialize variables
- done = 0;
- spaceDone = 0;
- inComment = 0;
-
- tok.strValue = "";
-
- // If the previous cycle had to read the next char (and stored it), it
is
- // now used as first read
- if tok.nextChar == 0 {
- singleChar = libgogo.GetChar(fd)
- } else {
- singleChar = tok.nextChar;
- tok.nextChar = 0;
- }
-
- // check if it is a valid read, or an EOF
- if singleChar == 0 {
-
tok.id = TOKEN_EOS;
- done = 1;
- spaceDone = 1;
- }
-
- //
- // Cleaning Tasks
- // The next part strips out spaces, newlines, tabs, and comments
- // Comments can either be single line with double slashes (//) or
multiline
- // using C++ syntax /* */
- //
- for ; spaceDone != 1; {
-
- // check whether a comment is starting
- if singleChar == '/' {
- // if we are in a comment skip the rest, get the next char
otherwise
- if inComment == 0 {
- singleChar = libgogo.GetChar(fd);
- if singleChar == '/' {
- // we are in a single line comment (until newline is
found)
- inComment = 1;
- } else {
- if singleChar == '*' {
- // we are in a multiline comment (until ending is
found)
- inComment = 2;
- } else {
- libgogo.ExitError(">> Scanner: Unkown character
combination for comments. Exiting.",1);
- }
- }
- }
- }
-
- // check whether a multi-line comment is ending
- if singleChar == '*' {
- singleChar = libgogo.GetChar(fd);
- if singleChar == '/' {
- if inComment == 2 {
- inComment = 0;
- singleChar = libgogo.GetChar(fd);
- }
- }
- }
-
- // if character is a newline:
- // *) if in a singleline comment, exit the comment
- // *) skip otherwise
- if singleChar == 10 {
- if inComment == 1 {
- inComment = 0;
- }
- }
-
- // handle everything that is not a space,tab,newline
- if singleChar != ' ' && singleChar != 9 && singleChar != 10 {
- // if not in a comment we have our current valid char
- if inComment == 0 {
- spaceDone = 1;
- }
-
- // check if GetChar() returned EOF while skipping
- if singleChar == 0 {
-
tok.id = TOKEN_EOS;
- spaceDone = 1;
- done = 1;
- }
- }
-
-
- // if we are not done until now, get a new character and start
another abolishing cycle
- if spaceDone == 0 {
- singleChar=libgogo.GetChar(fd);
- }
- }
-
- //
- // Actual scanning part starts here
- //
-
- // Catch identifiers
- // identifier = letter { letter | digit }.
- if (done != 1) && (singleChar >= 'A' && singleChar <= 'Z') ||
(singleChar >= 'a' && singleChar <= 'z') || singleChar == '_' { // check
for letter or _
-
tok.id = TOKEN_IDENTIFIER;
- // preceding characters may be letter,_, or a number
- for ; (singleChar >= 'A' && singleChar <= 'Z') || (singleChar
>= 'a' && singleChar <= 'z') || singleChar == '_' || (singleChar >= '0' &&
singleChar <= '9'); singleChar = libgogo.GetChar(fd) {
- tmp_TokAppendStr(tok,singleChar);
- }
- // save the last read character for the next GetNextToken() cycle
- tok.nextChar = singleChar;
- done = 1;
- }
-
- // string "..."
- if (done != 1) && singleChar == '"' {
-
tok.id = TOKEN_STRING;
- for singleChar = libgogo.GetChar(fd); singleChar != '"'
&&singleChar > 31 && singleChar < 127;singleChar = libgogo.GetChar(fd) {
- tmp_TokAppendStr(tok,singleChar);
- }
- if singleChar != '"' {
- libgogo.ExitError(">> Scanner: String not closing.
Exiting.",1);
- }
- done = 1;
- }
-
- // Single Quoted Character
- if (done != 1) && singleChar == 39 {
- singleChar = libgogo.GetChar(fd);
- if singleChar != 39 && singleChar > 31 && singleChar < 127 {
-
tok.id = TOKEN_INTEGER;
- tok.intValue = libgogo.ToIntFromByte(singleChar);
- } else {
- libgogo.ExitError(">> Scanner: Unknown character. Exiting.",1);
- }
- singleChar = libgogo.GetChar(fd);
- if singleChar != 39 {
- libgogo.ExitError(">> Scanner: Only single characters allowed.
Use corresponding integer for special characters. Exiting.",1);
- }
- done = 1;
- }
-
- // left brace (
- if (done != 1) && singleChar == '(' {
-
tok.id = TOKEN_LBRAC;
- done = 1;
- }
-
- // right brace )
- if (done != 1) && singleChar == ')' {
-
tok.id = TOKEN_RBRAC;
- done = 1;
- }
-
- // left square bracket [
- if (done != 1) && singleChar == '[' {
-
tok.id = TOKEN_LSBRAC;
- done = 1;
- }
-
- // right square bracket ]
- if (done != 1) && singleChar == ']' {
-
tok.id = TOKEN_RSBRAC;
- done = 1;
- }
-
- // integer
- if (done != 1) && singleChar > 47 && singleChar < 58 {
- var byteBuf [255]byte;
- var i uint64;
-
- for i = 0; singleChar > 47 && singleChar < 58 ; singleChar =
libgogo.GetChar(fd) {
- byteBuf[i] = singleChar;
- i = i +1;
- }
-
- tok.nextChar = singleChar;
-
tok.id = TOKEN_INTEGER;
- tok.intValue = libgogo.ByteBufToInt(byteBuf,i);
-
- done = 1;
- }
-
- // Left curly bracket '{'
- if (done != 1) && singleChar == '{' {
-
tok.id = TOKEN_LCBRAC;
- done = 1;
- }
-
- // Right curly bracket '}'
- if (done != 1) && singleChar == '}' {
-
tok.id = TOKEN_RCBRAC;
- done = 1;
- }
-
- // Point '.'
- if (done != 1) && singleChar == '.' {
-
tok.id = TOKEN_PT;
- done = 1;
- }
-
- // Not ('!') or Not Equal ('!=')
- if (done != 1) && singleChar == '!' {
- singleChar = libgogo.GetChar(fd);
- if singleChar == '=' {
-
tok.id = TOKEN_NOTEQUAL;
- } else {
-
tok.id = TOKEN_NOT;
- tok.nextChar = singleChar;
- }
- done = 1;
- }
-
- // Semicolon ';'
- if (done != 1) && singleChar == ';' {
-
tok.id = TOKEN_SEMICOLON;
- done = 1;
- }
-
- // Colon ','
- if (done != 1) && singleChar == ',' {
-
tok.id = TOKEN_COLON;
- done = 1;
- }
-
- // Assignment '=' or Equals comparison '=='
- if (done != 1) && singleChar == '=' {
- singleChar = libgogo.GetChar(fd);
- if singleChar == '=' {
-
tok.id = TOKEN_EQUALS;
- } else {
-
tok.id = TOKEN_ASSIGN;
- tok.nextChar = singleChar;
- }
- done = 1;
- }
-
- // AND Relation '&&'
- if (done != 1) && singleChar == '&' {
- singleChar = libgogo.GetChar(fd);
- if singleChar == '&' {
-
tok.id = TOKEN_REL_AND;
- } else {
-
tok.id = TOKEN_OP_ADR;
- tok.nextChar = singleChar;
- }
- done = 1;
- }
-
- // OR Relation '||'
- if (done != 1) && singleChar == '|' {
- singleChar = libgogo.GetChar(fd);
- if singleChar == '|' {
-
tok.id = TOKEN_REL_OR;
- } else {
- libgogo.ExitError(">> Scanner: No binary OR (|) supported.
Only ||.",1);
- }
- done = 1;
- }
-
- // Greater and Greater-Than relation
- if (done != 1) && singleChar == '>' {
- singleChar = libgogo.GetChar(fd);
- if singleChar == '=' {
-
tok.id = TOKEN_REL_GTOE;
- } else {
-
tok.id = TOKEN_REL_GT;
- tok.nextChar = singleChar;
- }
- done = 1;
- }
-
- // Less and Less-Than relation
- if (done != 1) && singleChar == '<' {
- singleChar = libgogo.GetChar(fd);
- if singleChar == '=' {
-
tok.id = TOKEN_REL_LTOE;
- } else {
-
tok.id = TOKEN_REL_LT;
- tok.nextChar = singleChar;
- }
- done = 1;
- }
-
- if (done != 1) && singleChar == '+' {
-
tok.id = TOKEN_ARITH_PLUS;
- done = 1;
- }
-
- if (done != 1) && singleChar == '-' {
-
tok.id = TOKEN_ARITH_MINUS;
- done = 1;
- }
-
- if (done != 1) && singleChar == '*' {
-
tok.id = TOKEN_ARITH_MUL;
- done = 1;
- }
-
- if (done != 1) && singleChar == '/' {
-
tok.id = TOKEN_ARITH_DIV;
- done = 1;
- }
-
- if done != 1 {
-
- libgogo.PrintString(">> Scanner: Unkown char '");
- libgogo.PrintChar(singleChar);
- libgogo.PrintString("'. ");
- libgogo.ExitError("Exiting.",1);
- }
-}
-
-
-//
-// GetNextToken should be called by the parser. It bascially fetches the
next
-// token by calling GetNextTokenRaw() and filters the identifiers for known
-// keywords.
-//
-func GetNextToken(fd uint64, tok *Token) {
- GetNextTokenRaw(fd,tok)
-
- // Convert identifier to keyworded tokens
- if
tok.id == TOKEN_IDENTIFIER {
- if libgogo.StringCompare("if",tok.strValue) != 0 {
-
tok.id = TOKEN_IF;
- }
- if libgogo.StringCompare("for",tok.strValue) != 0 {
-
tok.id = TOKEN_FOR;
- }
- if libgogo.StringCompare("type",tok.strValue) != 0 {
-
tok.id = TOKEN_TYPE;
- }
- if libgogo.StringCompare("const",tok.strValue) != 0 {
-
tok.id = TOKEN_CONST;
- }
- if libgogo.StringCompare("var",tok.strValue) != 0 {
-
tok.id = TOKEN_VAR;
- }
- if libgogo.StringCompare("struct", tok.strValue) != 0 {
-
tok.id = TOKEN_STRUCT;
- }
- if libgogo.StringCompare("return", tok.strValue) != 0 {
-
tok.id = TOKEN_RETURN;
- }
- if libgogo.StringCompare("func", tok.strValue) != 0 {
-
tok.id = TOKEN_FUNC;
- }
- if libgogo.StringCompare("import", tok.strValue) != 0 {
-
tok.id = TOKEN_IMPORT;
- }
- if libgogo.StringCompare("package", tok.strValue) != 0 {
-
tok.id = TOKEN_PACKAGE;
- }
- }
-}
-
-//
-// Debugging and temporary functions
-//
-
-func debugToken(tok *Token) {
- libgogo.PrintString("---------------------\n");
- libgogo.PrintString("Token Id: ");
- libgogo.PrintNumber(
tok.id);
- libgogo.PrintString("\n");
- if
tok.id == TOKEN_IDENTIFIER ||
tok.id == TOKEN_STRING {
- libgogo.PrintString("Stored string: ");
- fmt.Printf(tok.strValue);
- libgogo.PrintString("\n");
- }
- if
tok.id == TOKEN_INTEGER {
- libgogo.PrintString("Stored integer: ");
- libgogo.PrintNumber(tok.intValue);
- libgogo.PrintString("\n");
- }
-}
-
-// Temporary test function
-func ScannerTest(fd uint64) {
- var tok Token;
-
-
tok.id = 0;
- tok.nextChar = 0;
-
- for GetNextToken(fd,&tok);
tok.id != TOKEN_EOS; GetNextToken(fd,&tok) {
- debugToken(&tok);
- }
-}
-
-func tmp_TokAppendStr(tok *Token, b byte) {
- tok.strValue += string(b);
-}
=======================================
--- /testing/tests/2010-03-21_token.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package main
-
-//
-// Set of recognized tokens
-//
-const TOKEN_IDENTIFIER uint64 = 1; // Identifier
-const TOKEN_STRING uint64 = 2; // String using "..."
-const TOKEN_EOS uint64 = 3; // End of Scan
-const TOKEN_LBRAC uint64 = 4; // Left bracket '('
-const TOKEN_RBRAC uint64 = 5; // Right bracket ')'
-const TOKEN_LSBRAC uint64 = 6; // Left square bracket '['
-const TOKEN_RSBRAC uint64 = 7; // Right square bracket ']'
-const TOKEN_INTEGER uint64 = 8; // Integer number
-const TOKEN_LCBRAC uint64 = 9; // Left curly bracket '{'
-const TOKEN_RCBRAC uint64 = 10; // Right curly bracket '}'
-const TOKEN_PT uint64 = 11; // Point '.'
-const TOKEN_NOT uint64 = 12; // Boolean negation '!'
-const TOKEN_NOTEQUAL uint64 = 13; // Comparison, not equal '!='
-const TOKEN_SEMICOLON uint64 = 14; // Semi-colon ';'
-const TOKEN_COLON uint64 = 15; // Colon ','
-const TOKEN_ASSIGN uint64 = 16; // Assignment '='
-const TOKEN_EQUALS uint64 = 17; // Equal comparison '=='
-const TOKEN_CHAR uint64 = 18; // Single Quoted Character 'x'
-const TOKEN_REL_AND uint64 = 19; // AND Relation '&&'
-const TOKEN_REL_OR uint64 = 20; // OR Relation '||'
-const TOKEN_REL_GTOE uint64 = 21; // Greather-Than or Equal '>='
-const TOKEN_REL_GT uint64 = 22; // Greather-Than '>'
-const TOKEN_REL_LTOE uint64 = 23; // Less-Than or Equal '<='
-const TOKEN_REL_LT uint64 = 24; // Less-Than '<'
-const TOKEN_ARITH_PLUS uint64 = 25; // Arith. Plus '+'
-const TOKEN_ARITH_MINUS uint64 = 26;// Arith. Minus '-'
-const TOKEN_ARITH_MUL uint64 = 27; // Arith. Multiplication '*'
-const TOKEN_ARITH_DIV uint64 = 28; // Arith. Division '/'
-const TOKEN_OP_ADR uint64 = 29; // Address operator '&'
-
-//
-// Advanced tokens, that are generated in the 2nd step from identifiers
-// The tokens represent the corresponding language keywords.
-//
-const TOKEN_FOR uint64 = 101;
-const TOKEN_IF uint64 = 102;
-const TOKEN_TYPE uint64 = 103;
-const TOKEN_CONST uint64 = 104;
-const TOKEN_VAR uint64 = 105;
-const TOKEN_STRUCT uint64 = 106;
-const TOKEN_RETURN uint64 = 107;
-const TOKEN_FUNC uint64 = 108;
-const TOKEN_PACKAGE uint64 = 109;
-const TOKEN_IMPORT uint64 = 110;
-
-//
-// Helper functions
-//
-
-func TokenToString (id uint64) string {
- var retStr string;
-
- if id == TOKEN_IDENTIFIER {
- retStr = "<identifier>";
- }
- if id == TOKEN_STRING {
- retStr = "<string>";
- }
- if id == TOKEN_EOS {
- retStr = "<END-OF-SCAN>";
- }
- if id == TOKEN_LBRAC {
- retStr = "(";
- }
- if id == TOKEN_RBRAC {
- retStr = ")";
- }
- if id == TOKEN_LSBRAC {
- retStr = "[";
- }
- if id == TOKEN_RSBRAC {
- retStr = "]";
- }
- if id == TOKEN_INTEGER {
- retStr = "<integer>";
- }
- if id == TOKEN_LCBRAC {
- retStr = "{";
- }
- if id == TOKEN_RCBRAC {
- retStr = "}";
- }
- if id == TOKEN_PT {
- retStr = ".";
- }
- if id == TOKEN_NOT {
- retStr = "!";
- }
- if id == TOKEN_NOTEQUAL {
- retStr = "!=";
- }
- if id == TOKEN_SEMICOLON {
- retStr = ";";
- }
- if id == TOKEN_COLON {
- retStr = ",";
- }
- if id == TOKEN_ASSIGN {
- retStr = "=";
- }
- if id == TOKEN_EQUALS {
- retStr = "==";
- }
- if id == TOKEN_CHAR {
- retStr = "'<char>'";
- }
- if id == TOKEN_REL_AND {
- retStr = "&&";
- }
- if id == TOKEN_REL_OR {
- retStr = "||"
- }
- if id == TOKEN_REL_GTOE {
- retStr = ">=";
- }
- if id == TOKEN_REL_GT {
- retStr = ">";
- }
- if id == TOKEN_REL_LTOE {
- retStr = "<=";
- }
- if id == TOKEN_REL_LT {
- retStr = "<";
- }
- if id == TOKEN_ARITH_PLUS {
- retStr = "+";
- }
- if id == TOKEN_ARITH_MINUS {
- retStr = "-";
- }
- if id == TOKEN_ARITH_MUL {
- retStr = "*";
- }
- if id == TOKEN_ARITH_DIV {
- retStr = "/";
- }
- if id == TOKEN_OP_ADR {
- retStr = "&";
- }
- if id == TOKEN_FOR {
- retStr = "for";
- }
- if id == TOKEN_IF {
- retStr = "if";
- }
- if id == TOKEN_TYPE {
- retStr = "type";
- }
- if id == TOKEN_CONST {
- retStr = "const";
- }
- if id == TOKEN_VAR {
- retStr = "var";
- }
- if id == TOKEN_STRUCT {
- retStr = "struct";
- }
- if id == TOKEN_RETURN {
- retStr = "return";
- }
- if id == TOKEN_FUNC {
- retStr = "func";
- }
- if id == TOKEN_PACKAGE {
- retStr = "package";
- }
- if id == TOKEN_IMPORT {
- retStr = "import";
- }
-
- return retStr;
-}
=======================================
--- /testing/tests/2010-04-11_parse_imports_fail.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package main
-
-import "fmt"
-import "os"
-import "syscall"
-import this_is_not_a_string
-
-func main() {
-
-}
=======================================
--- /testing/tests/2010-04-11_struct1.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-type Token struct {
- id uint64;
- intValue uint64;
- strValue string;
- nextChar byte;
-};
=======================================
--- /testing/tests/2010-04-11_struct2.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-type Token struct {
- someArray [1]byte;
- someArray2 [2]uint64;
- someString string;
-};
=======================================
--- /testing/tests/2010-04-11_struct3_fail.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-type Token struct {
- someArray [1]byte
- someArray2 [2]uint64
- someString string
-};
=======================================
--- /testing/tests/2010-04-11_struct4_fail.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-type Token {
- someArray [1]byte;
- someArray2 [2]uint64;
- someString string;
-};
=======================================
--- /testing/tests/2010-04-11_struct5_fail.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-type Token struct {
- someArray [1]byte;
- someArray2 [2]uint64;
- someString string;
-}
=======================================
--- /testing/tests/2010-04-11_struct6_fail.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-type struct {
-}
=======================================
--- /testing/tests/2010-04-11_struct7.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-type Empty struct {
-};
=======================================
--- /testing/tests/2010-04-11_vardecl1.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-var simpleVar uint64;
-var simpleVar2 uint64;
-
=======================================
--- /testing/tests/2010-04-11_vardecl2.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-var simpleVar uint64 = 1;
-
=======================================
--- /testing/tests/2010-05-09_struct8_fail.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-type Test struct {
- refToSelf Test;
-};
=======================================
--- /testing/tests/2010-05-09_struct9.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-type Test struct {
- refToSelfPtr *Test;
-};
=======================================
--- /testing/tests/2010-05-09_symtable_fail.go Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2010 The GoGC Authors. All rights reserved.
-// Use of this source code is governed by the MIT
-// license that can be found in the LICENSE file.
-
-package testing
-
-var a unknown = 42;
=======================================
--- /testing/tests/test.go Tue Jun 8 10:20:44 2010
+++ /dev/null
@@ -1,100 +0,0 @@
-package main
-
-type foo struct {
- bar1 uint64;
- bar2 string;
- bar3 *uint64;
-};
-
-type test struct {
- bar foo;
- bazz [20]string;
- barPtr *foo;
-};
-
-var initTest byte = 1 + 2 * 3;
-var initTest2 uint64 = initTest + 1;
-var fooArrInst [10]foo;
-var testInst test;
-var testPtr *test;
-
-func test(bla uint64, blub string) {
- var a uint64 = 5;
- var b uint64 = 1;
- var c string = "Test";
- var d *string;
- var e byte;
- var f byte;
- b = e + f + 1 - a;
- a = 1 + b * a;
- c = fooArrInst[a].bar2;
- c[1] = testPtr.barPtr.bar2[1];
- d[2] = 'x';
- a = fooArrInst[b].bar1 + testInst.barPtr.bar1;
- fooArrInst[0].bar3 = &a;
- fooArrInst[0].bar3 = testPtr.barPtr.bar3;
- fooArrInst[a].bar3 = &a;
- fooArrInst[a].bar3 = testPtr.barPtr.bar3;
-
- if (a < 10) && (b > 10) || (a == 5) {
- if (b > 15) {
- b = 4;
- } else {
- b = 3;
- }
- } else {
- b = 2;
- }
-}
-
-func foo() uint64 {
- return 3;
-}
-
-func bar(a uint64) uint64 {
- return a;
-}
-
-func foobar(a uint64, b uint64, c uint64) uint64 {
- return a + b + c;
-}
-
-func bazz(a uint64) uint64 {
- var ret uint64;
- var tmp uint64 = 3;
- foo();
- tmp = bar(tmp);
- ret = foobar(a, tmp, 3);
- return ret;
-}
-
-func blub(r string) string {
- var x string = r;
- return x;
-}
-
-func main() {
- var ret uint64;
- var u string = "ABC";
- var x string;
- ret = bazz(1);
- x = blub(u);
- ret = bazz_fwd(1);
-}
-
-func foo_fwd() {
- var ret uint64;
- ret = bazz_fwd(1);
-}
-
-func bazz_fwd(b byte) uint64 {
- return b;
-}
-
-func muh() {
- var x string;
- x = maeh(x, x);
-}
-
-func maeh(y string, z string) string {
-}
=======================================
--- /testing/testsuite Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,294 +0,0 @@
-#!/bin/bash
-
-# Copyright 2009 The GoGC Authors. All rights reserved.
-# Use of this source code is governed by the MIT
-# license that can be found in the LICENSE file.
-
-#
-# This tool can test against predefined source files by comparing various
-# compiled results. New valid sets can be generated and need to be
-# acknowlegded before code can be tested against.
-#
-
-# change to this directory for easier handling of paths
-SELF="testsuite"
-BASEDIR=`dirname $0`
-cd $BASEDIR
-
-# tools that are used
-SHA256SUM=/usr/bin/sha256sum
-
-# configuration
-TESTDIR="tests"
-TMPDIR="tmp"
-GOGODIR=../src
-GOGO=$GOGODIR/gogo
-
-# Performs internal checks to make sure everything is set up.
-function do_checks() {
- echo ""
- echo ">>> Performing internal checks"
- echo ""
-
- echo -n "Checking for sha256sum tool... "
- if [ -e $SHA256SUM ]; then
- echo "ok"
- else
- echo "failed"
- exit 1
- fi
-
- echo -n "Checking for gogo compiler... "
- if [ -e $GOGO ]; then
- echo "ok"
- else
- echo "failed"
- exit 1
- fi
-
- echo -n "Checking for $TESTDIR... "
- if [ -d $TESTDIR ]; then
- echo "ok"
- else
- echo "failed"
- exit 1
- fi
-}
-
-# Generates new results that can be marked as valid
-function new_valids() {
- do_checks
-
- echo ""
- echo ">>> Checking whether there exists an acknowledged resultset"
- if [ -e checksums ]; then
- echo ""
- echo "* Found an already acknowledged resultset."
- echo "* To create a new one run 'fullclean' first."
- exit 1
- fi
-
- echo ""
- echo ">>> Generating new resultset"
- echo ""
-
- echo -n "Checking for $TMPDIR... "
- if [ -d $TMPDIR ]; then
- echo "ok"
- else
- echo "creating it"
- mkdir $TMPDIR
- fi
-
- for filename in $( ls $TESTDIR )
- do
- $GOGO -p $TESTDIR/$filename > $TMPDIR/$filename
- done
- $GOGO -c $TESTDIR/test.go
- mv _gogo_.sog $TMPDIR
-
- echo ""
- echo "* Generated testsuite results in $TMPDIR"
- echo "* Please check if these results are expected"
- echo "* The suite may then be acknowledged using the 'ackvalids'
action"
-}
-
-# Acknowledges the previously generated results
-function ack_valids() {
- do_checks
-
- echo ""
- echo ">>> Checking for already acknowledged resultset"
- echo ""
- if [ -e checksums ]; then
- echo "* Found an already acknowledged resultset."
- echo "* To create a new one run 'fullclean' and 'newvalids'."
- exit 1
- fi
-
- echo ">>> Checking for a new resultset"
- echo ""
- echo -n "Checking for $TMPDIR... "
- if [ -d $TMPDIR ]; then
- echo "ok"
- else
- echo "failed"
- exit 1
- fi
-
- echo ""
- echo ">>> Acknowledging the generated results"
- echo ""
-
- for filename in $( ls $TMPDIR )
- do
- result=$($SHA256SUM $TMPDIR/$filename)
- echo "$result"
- echo "$result" >> checksums
- done
-
- echo ""
- echo ">>> Preparing resultset"
- echo ""
-
- echo -n "Renaming $TMPDIR to results... "
- mv $TMPDIR results
- if [ "$?" -eq 0 ]; then
- echo "ok"
- else
- exit 1
- fi
-
-}
-
-# Performs a checksum comparison against the previously acked results
-function do_tests() {
- do_checks
-
- echo ""
- echo ">>> Checking whether an acknowledged resultset exists"
- echo ""
- if [ ! -e checksums ]; then
- echo "* No acknowledged resultset found"
- exit 1
- fi
-
- echo ">>> Generating tests"
- echo ""
- echo -n "Checking for $TMPDIR... "
- if [ -d $TMPDIR ]; then
- echo "ok"
- else
- echo "creating it"
- mkdir $TMPDIR
- fi
-
- rm -f test-diffs
-
- for filename in $( ls $TESTDIR )
- do
- $GOGO -p $TESTDIR/$filename > $TMPDIR/$filename
- done
- $GOGO -c $TESTDIR/test.go
- mv _gogo_.sog $TMPDIR
-
- echo ""
- echo ">>> Performing quick check"
- echo ""
- $SHA256SUM --quiet -c checksums
-
- if [ "$?" -eq 0 ]; then
- echo "* Checksums matched. Everything seems fine"
- else
- echo ""
- echo ">>> Checksums didn't match. Printing failed diffs"
- echo ""
- while read line
- do
- IFS=" "
- arr=($line)
- csum=($($SHA256SUM ${arr[1]}))
- if [ ${csum[0]} != ${arr[0]} ]; then
- IFS="/"
- path=(${arr[1]})
- diff -u "results/${path[1]}" "${arr[1]}"
- echo $(diff -u "results/${path[1]}" "${arr[1]}") >>
test-diffs
- echo ""
- fi
- done < checksums
- fi
-}
-
-function do_clean() {
-
- echo ""
- echo ">>> Cleaning test results"
- echo ""
-
- echo -n "Removing $TMPDIR... "
- if [ -d $TMPDIR ]; then
- rm -r $TMPDIR
- echo "ok"
- else
- echo "not needed"
- fi
-
- echo -n "Removing test-diffs... "
- if [ -e test-diffs ]; then
- rm test-diffs
- echo "ok"
- else
- echo "not needed"
- fi
-}
-
-function do_fullclean() {
-
- echo ""
- echo ">>> Cleaning"
- echo ""
-
- echo -n "Removing $TMPDIR... "
- if [ -d $TMPDIR ]; then
- rm -r $TMPDIR
- echo "ok"
- else
- echo "not needed"
- fi
-
- if [ -e checksums ]; then
- echo -n "Removing checksums file... "
- rm checksums
- if [ "$?" -eq 0 ]; then
- echo "ok"
- else
- exit 1
- fi
- fi
-
- echo -n "Removing results... "
- if [ -d results ]; then
- rm -r results
- echo "ok"
- else
- echo "not needed"
- fi
-}
-
-function do_help() {
- echo ""
- echo ">>> GoGC testsuite"
- echo ""
- echo "* newvalids ... generate a new valid resultset (requires
fullclean)"
- echo "* ackvalids ... validate a freshley generated resultset"
- echo "* fullclean ... clean generated and/or acknowledged results"
- echo "* test ........ perform tests against an acknowlegded resultset"
- echo "* clean ....... clean the temporary generated results"
- echo "* help ........ display this help"
-}
-
-case $1 in
- newvalids)
- new_valids
- ;;
- ackvalids)
- ack_valids
- ;;
- test)
- do_tests
- ;;
- fullclean)
- do_fullclean
- ;;
- clean)
- do_clean
- ;;
- help)
- do_help
- ;;
- *)
- echo "Usage: $SELF {newvalids|ackvalids|fullclean|test|clean|help}"
>&2
- ;;
-esac
-exit 0
-
==============================================================================
Revision: 7b2b6ce070
Author: Scott Lawrence <
byt...@gmail.com>
Date: Wed Aug 18 11:27:37 2010
Log: moved docs/latex to docs/paper/latex
http://code.google.com/p/gogc/source/detail?r=7b2b6ce070
Added:
/docs/paper/latex/Makefile
/docs/paper/latex/files/building.pdf
/docs/paper/latex/gogo.bib
/docs/paper/latex/gogo.tex
Deleted:
/docs/latex/Makefile
/docs/latex/files/building.pdf
/docs/latex/gogo.bib
/docs/latex/gogo.tex
=======================================
--- /dev/null
+++ /docs/paper/latex/Makefile Wed Aug 18 11:27:37 2010
@@ -0,0 +1,8 @@
+all:
+ pdflatex gogo.tex
+ bibtex gogo
+ pdflatex gogo.tex
+ pdflatex gogo.tex
+
+clean:
+ rm -rf *.bbl *.log *.toc *.aux *.out *.blg *.pdf
=======================================
--- /dev/null
+++ /docs/paper/latex/files/building.pdf Wed Aug 18 11:27:37 2010
Binary file, no diff available.
=======================================
--- /dev/null
+++ /docs/paper/latex/gogo.bib Wed Aug 18 11:27:37 2010
@@ -0,0 +1,71 @@
+@Book{
+ wir96,
+ author = {{Wirth, N.}},
+ title = {{Compiler Construction}},
+ publisher = {{Addison-Wesley}},
+ year = {1996},
+ lanuage = {english}
+}
+
+@Misc{
+ goo10,
+ author = {{Google Inc.}},
+ title = {{The Go Programming Language Specification}},
+ howpublished = {\url{
http://golang.org/doc/go_spec.html} (4.6.2010)},
+ year = {2010},
+ language = {english}
+}
+
+@Misc{
+ pik00,
+ author = {{Pike, R.}},
+ title = {{A Manual for the Plan 9 assembler}},
+ howpublished = {\url{
http://doc.cat-v.org/plan_9/4th_edition/papers/asm}
(4.6.2010)},
+ year = {2000},
+ language = {english}
+}
+
+@Misc{
+ int09,
+ author = {{Intel Inc.}},
+ title = {{Intel 64 and IA-32 Architectures Software Developer's Manual,
Volume 2A: Instruction Set Reference, A-M}},
+ howpublished =
{\url{
http://www.intel.com/products/processor/manuals/index.htm}
(9.6.2010)},
+ year = {2009},
+ language = {english}
+}
+
+@Misc{
+ var97,
+ author = {{Various}},
+ title = {{brk(2) -- Linux man page}},
+ howpublished = {\url{
http://linux.die.net/man/2/brk} (9.6.2010)},
+ year = {1997},
+ language = {english}
+}
+
+@Misc{
+ var10,
+ author = {{Various}},
+ title = {{The Linux Kernel}},
+ howpublished = {\url{
http://www.kernel.org} (9.6.2010)},
+ year = {2010},
+ language = {english}
+}
+
+@Misc{
+ var08,
+ author = {{Various}},
+ title = {{syscalls(2) -- Linux man page}},
+ howpublished = {\url{
http://linux.die.net/man/2/syscalls} (9.6.2010)},
+ year = {2008},
+ language = {english}
+}
+
+@Misc{
+ var06,
+ author = {{Various}},
+ title = {{proc(5) -- Linux man page}},
+ howpublished = {\url{
http://linux.die.net/man/5/proc} (9.6.2010)},
+ year = {2006},
+ language = {english}
+}
=======================================
--- /dev/null
+++ /docs/paper/latex/gogo.tex Wed Aug 18 11:27:37 2010
@@ -0,0 +1,682 @@
+\documentclass[a4paper]{scrartcl}
+
+\let\chapter\section
+\let\section\subsection
+\let\subsection\subsubsection
+\let\subsubsection\paragraph
+\let\paragraph\subparagraph
+\let\subparagraph\undefined
+
+\usepackage{booktabs}
+\usepackage[usenames,dvipsnames]{color}
+\usepackage[latin1]{inputenc}
+\usepackage{listings}
+\usepackage[english]{babel}
+\usepackage[pdftex,plainpages=false,pdfpagelabels,
+ hyperfootnotes=false]{hyperref}
+\hypersetup{pdftitle={GoGC -- A Go compiler written in Go},
+ pdfauthor={Michael Lippautz, Andreas Unterweger},
+ pdfsubject={GoGC},pdfkeywords={Go,Compiler,GoGC}}
+\usepackage{graphicx}
+
+\definecolor{lightgray}{RGB}{250,250,250}
+
+\lstset{
+ basicstyle=\small,
+ frame=lines,
+ backgroundcolor=\color{lightgray}
+}
+
+\title{GoGC\\ \large{A Go compiler written in Go}}
+\author{
+ Michael~Lippautz \\ \normalsize{\
texttt{michael....@sbg.ac.at}}
+ \and
+ Andreas~Unterweger \\ \normalsize{\
texttt{andreas.u...@sbg.ac.at}}
+}
+
+\date{\today}
+
+\begin{document}
+ \maketitle
+ \tableofcontents
+
+ \chapter{Introduction}
+ GoGC is a self-compiling (see section \ref{chpt:building}) Go compiler
+ written in Go which implements scanning, parsing and code generation
for a
+ subset of the Go language \cite{goo10}. It is mostly compatible with
the Go
+ compiler available at \cite{goo10} and outputs valid Plan9 assembly
code
+ which can be assembled by the latter as well as the Plan9 assembly
tools
+ \texttt{6a} and \texttt{6l}\cite{pik00}.\\
+
+
+ \chapter{Input language}
+ Go is a programming language developed by Google, based on a C like
syntax and fully specified in \cite{goo10}. The input language follows the
one defined by Go. This results in programs being able to be compiled by
the official Go compilers and GoGC.
+
+ \section{Some differences to Go}
+ \begin{enumerate}
+ \item GoGC only provides only a \textbf{very} basic featureset.
Expect
+ every advanced and interesting feature to be missing.
+ \item GoGC forces the usage of semicolons at the end of statements,
+ while in actual Go this token is optional. This restriction was
made
+ to make parsing easier.
+ \item Go is fully Unicode compatible, while GoGC uses ASCII
characters only.
+ \item Simplified expressions, following Wirth's
defintions\cite{wir96}.
+ \end{enumerate}
+
+ \section{EBNF}
+ \label{sec:ebnf}
+ The following section deals with the input language specification in
+ EBNF form. Additionally to the specification below, GoGC also allows
+ source code comments following the C++ multiline
style(\texttt{/* ... */})
+ and the C inline style (\texttt{//}).
+
+ \subsection*{Atoms}
+ The following listing describes the basic atoms that are possible
in
+ GoGC programs.
+ \begin{lstlisting}[caption=Atoms]
+single_char = CHR(32)|...|CHR(127).
+char = "'" single_char "'".
+string = """ {single_char} """.
+
+digit = "0"|...|"9".
+integer = digit {digit}.
+
+letter = "a"|...|"z"|"A"|...|"Z"|"_".
+identifier = letter { letter | digit }.
+selector = { "." identifier
+ | "[" (integer | identifier selector) "]" }.
+ \end{lstlisting}
+
+ \subsection*{Expressions}
+ Although not as expressive as the ones from Go, these rules define
expressions that have comparisons, relations and arithmetical terms.
+
+ \begin{lstlisting}[caption=Expressions]
+cmp_op = ">" | "<" | ">=" | "<=" | "==" | "!=".
+unary_arith_op = "+" | "-".
+binary_arith_op = "*" | "/" .
+
+factor = identifier selector | integer | char | string
+ | "(" expression ")" | "!" factor.
+term = factor { (binary_arith_op | "&&") factor}.
+simple_expression = [ unary_arith_op ] term
+ { (unary_arith_op | "||") term }.
+expression = "&" identifier selector
+ | simple_expression [ cmp_op simple_expression ].
+ \end{lstlisting}
+
+ \subsection*{Types and Variable Declarations}
+
+ \begin{lstlisting}[caption=Types]
+type = ([ "[" integer "]" ] identifier | "uint64" | "byte")
+ | "string".
+var_decl = "var" identifier type [ "=" expression ] ";".
+var_decl_list = { var_decl }
+ \end{lstlisting}
+
+ \subsection*{Structs}
+
+ \begin{lstlisting}[caption=Structs]
+struct_var_decl = identifier type ";".
+struct_var_decl_list = { struct_var_decl }.
+struct_decl = "type" identifier "struct" "{"
+ struct_var_decl_list "}" ";".
+struct_decl_list = { struct_decl }.
+ \end{lstlisting}
+
+ \subsection*{Statements}
+
+ \begin{lstlisting}[caption=Statements]
+package_stmt = "package" identifier ";".
+import_stmt = "import" string.
+import_stmt_list = { import_stmt }.
+
+stmt_sequence = { stmt }
+stmt = assignment ";" | function_call_stmt ";" | if_stmt
+ | for_stmt | ";".
+
+assignment = identifier selector "=" expression
+if_stmt = "if" expression "{" stmt_sequence "}" [ else_stmt ].
+else_stmt = "else" "{" stmt_sequence "}".
+for_stmt = "for" [assignment] ";" [expression] ";" [assignment]
+ "{" stmt_sequence "}".
+ \end{lstlisting}
+
+ \subsection*{Functions}
+
+ \begin{lstlisting}[caption=Functions]
+expression_list = expression { "," expression }.
+function_call = "(" [expression_list] ")".
+function_call_stmt = identifier selector function_call.
+
+identifier_type = identifier [ "*" ] type.
+identifier_type_list = [ identifier_type
+ { "," identifier_type } ].
+func_decl_head = "func" identifier "(" identifier_type_list ")" [type].
+func_decl = "{" var_decl_list stmt_sequence
+ ["return" expression ";"] "}".
+func_decl_raw = ";".
+func_decl_list = { func_decl_head (func_decl | func_decl_raw)
+ \end{lstlisting}
+
+ \subsection*{The GoGC Program}
+ Finally, the main program structure is defined by
\texttt{go\_program}. The sequence of the various program parts has been
forced to the following to make parsing easier.
+
+ \begin{lstlisting}[caption=GoGC Program]
+go_program = package_stmt import_stmt_list struct_decl_list
+ var_decl_list func_decl_list.
+ \end{lstlisting}
+
+
+ \chapter{Output language}
+ The output language is Plan-9 assembler \cite{pik00}. It is a modified
version of 64 bit assembly for Intel x86 processors with AT\&T syntax that
has been created by Bell Labs to be used in their compiler and assembler
collection.
+
+ \section{Assembly output}
+ GoGC creates an output file with assembly instructions and comments
using mnemonics for op codes and operands/registers which means that it
outputs in text form, not in binary form. Thereforce, an assembler is
needed to process the output in order to make it executable. Like the Go
compiler, GoGC relies on \texttt{6a} and \texttt{6l} of the Plan9 tools in
order to acomplish this\cite{pik00}.\\
+ The assembly output consists basically of three sections: the data
segment, the initialization segment and the code segment. GoGC's assembly
output framework provides basic output routines which make it possible to
switch between those three segments. Whereas the data segment is used to
reserve space for global variables and strings in the data segment, the
initialization segment and the code segment contain the code for global
variable initialization and the functions from the input, respectively. All
other functions (code generation for arithmetical expressions etc.) rely on
the assembly output framework which is also able to place comments with the
corresponding input file name and line number for debugging purposes in the
output file.
+
+ \chapter{Scanner / Parser}
+ The scanner is basically the provider of tokens that are used by the
parser
+ to process the code. In order to generate these tokens, the scanner
reads
+ the file character by character. If a sequence is known, it converts
this
+ sequence of characters into the corresponding token. Tokens generated
this
+ way are called simple tokens, as they can be generated right away. For
+ instance, the sequence \textit{'A'} can be directly converted into a
token
+ representing the byte value 65. \\
+
+
+
+ Before providing a token to the parser, the scanner may convert such
+ simple tokens one more time. These complex tokens are generated from
simple
+ ones that represent \texttt{identifiers}. \texttt{Identifiers} are
compared to a
+ predefined list of keywords. If a keyword matches a token value, the
token
+ is converted to the one representing the keyword. Table
\ref{tbl:tokens}
+ lists some of these tokens.
+
+ \begin{table}[htb]
+ \centering
+ \begin{tabular}{ll}
+ \toprule
+ Simple tokens & \texttt{\&\&}, \texttt{+}, \texttt{-},
\texttt{\{}, \texttt{\}}, \texttt{$($}, \texttt{$)$}, \dots \\
+ Complex tokens & \texttt{for}, \texttt{if}, \texttt{else},
\texttt{func}, \texttt{type} \\
+ \bottomrule
+ \end{tabular}
+ \caption{Token examples}
+ \label{tbl:tokens}
+ \end{table}
+
+ The scanner also implements a very simple escaping mechanism that
allows
+ sequences like \textit{'\textbackslash n'} to be used in strings. \\
+ Comments can be written as \textit{/* ... */} blocks or
+ \textit{\textbackslash \textbackslash} until the line ending, like in
C/C++.
+ \\ \\
+ The parser then takes these tokens and represents the language defined
by
+ the EBNF from section \ref{sec:ebnf}. The parser is basically
implemented
+ as LL1 like in \cite{wir96}, with one minor difference. In order to be
+ compatible with Go it was necesarry to include one namespace hierachy
that
+ is represented by packages. Since this name scope is prefixed
+ using \texttt{package.}, the parser needs a lookup of three (LL3)in
this
+ case.
+
+ \chapter{Symbol table}
+ In order to be able to lookup local and global variable names as well
as function names, a symbol table is required. Based on \cite{wir96},
object and type descriptors were used, each containing the information
required for lookup and code generation. Object descriptors are used to
store information about variables and parameters whereas type descriptors
are used to store information about types and functions.\\
+ The following tables \ref{tbl:objectdesc} and \ref{tbl:typedesc}
summarize the fields of the object and type descriptors and their
respective purpose. Some fields had to be added in order to support forward
declarations and the distinction between values and pointers.
+ \begin{table}[htb]
+ \centering
+ \begin{tabular}{lcl}
+ \toprule
+ \textbf{Field} & \textbf{Type} & \textbf{Purpose}\\
+ \midrule
+ Name & \texttt{string} & The object's name\\
+ PackageName & \texttt{string} & The object's package (Go name
space)\\
+ Class & \texttt{uint64} & The descriptors's kind (variable, field,
parameter)\\
+ ObjType & \texttt{*TypeDesc} & The object's type\\
+ PtrType & \texttt{uint64} & If 1, the object's type is
\texttt{*ObjType}; if 0, \texttt{ObjType}\\
+ Next & \texttt{*ObjType} & Next object (linked list)\\
+ \bottomrule
+ \end{tabular}
+ \caption{ObjectDesc}
+ \label{tbl:objectdesc}
+ \end{table}
+
+ \begin{table}[htb]
+ \centering
+ \begin{tabular}{lc p{0.6\textwidth}}
+ \toprule
+ \textbf{Field} & \textbf{Type} & \textbf{Purpose}\\
+ \midrule
+ Name & \texttt{string} & The type's/function's name\\
+ PackageName & \texttt{string} & The type's/function's package (Go
name space)\\
+ ForwardDecl & \texttt{uint64} & If 1, the type/function has not
yet been fully delcared/implemented\\
+ Form & \texttt{uint64} & The descriptor's kind (simple type, array
type, struct type, function)\\
+ Len & \texttt{uint64} & For simple types: type size in bytes, for
arrays: array size\\
+ Fields & \texttt{*ObjDesc} & For struct types: struct fields, for
functions: function parameters\\
+ Base & \texttt{*TypeDesc} & For array types: the array base type\\
+ Next & \texttt{*TypeDesc} & Next type/function (linked list)\\
+ \bottomrule
+ \end{tabular}
+ \caption{TypeDesc}
+ \label{tbl:typedesc}
+ \end{table}
+
+ For both global and function-local symbol tables the build-up and
lookup is integrated into the parser. Whenever sufficient information
(variable name, function name, type name; optionally preceeded by a package
name) is encountered, a lookup in the symbol table is issued. Declarations
issue new symbol table entries with the corresponding descriptor properties
as described above.\\
+ Forward declarations are currently only supported for type pointers
(as pointers are always 64 bits in size) and functions (as the affected
offsets can be fixed by the linker if necessary). Whenever supported
forward declarations are encountered, a new symbol table entry is created
with \texttt{ForwardDecl} set to 1. Forward declared function can then be
called, although forward declared type pointers cannot be dereferred until
the size of the type they are pointing to is known (\texttt{ForwardDecl} is
0). When forward declared functions are implemented, the corresponding
symbol table entry is modified (\texttt{ForwardDecl} is set to 0) instead
of creating a new one.
+
+ \section{Supported data types}
+ GoGC supports 4 built-in value types and the declaration of new
struct and array types as well as pointers to value, struct and array
types. The 4 built-in data types are based on the data types supported by
the Go compiler and form a minimal subset of them in order to perform basic
integer and string operations. The following table \ref{tbl:types} lists
the built-in value types, together with their purpose and size.
+
+ \begin{table}[htb]
+ \centering
+ \begin{tabular}{cc p{0.5\textwidth}}
+ \toprule
+ \textbf{Type} & \textbf{Size} & \textbf{Purpose}\\
+ \midrule
+ \texttt{uint64} & 8 bytes (64 bits) & Unsigned integer with the
target platform's register size\\
+ \texttt{byte} & 1 byte (8 bits) & Single ASCII character or
unsigned 8 bit integer value\\
+ \texttt{string} & 16 bytes (see section \ref{String constants}) &
Character sequences\\
+ \texttt{bool} & 8 bytes (64 bits) & Internal type used for
comparisions and jumps\\
+ \bottomrule
+ \end{tabular}
+ \caption{Built-in types}
+ \label{tbl:types}
+ \end{table}
+
+ \section{Local variables and offset calculations}
+ In order to be able to distinguish between parameters, local and
global variables, a global and a local symbol table as well the function's
parameters as third, virtual symbol table are used. Local variables hide
global variables of the same name by performing the symbol table lookup for
local variables and parameters first and returning the first match if there
is any.\\
+ The memory layout for local and global variables as well as
parameters is equal: the object's offset address contains the first 64 bits
of the object, the next highest address (offset address plus 64 bits)
contains the next 64 bits etc. All local and global variable offset
addresses are 64 bit aligned. The offset of an object can be calculated by
summing the aligned sizes of its predecessors in the corresponding variable
list. Doing this, it has to be taken into consideration that pointers
always occupy 8 bytes (64 bits), regardless of the type they are actually
pointing to.\\
+ Global variables start at offset 0 of the data segment, referred to
as \texttt{data+0} in the output. Subsequent global variables use ascending
offsets as described above (p.e. referred to as \texttt{data+8} for offset
8). Local variables and parameters are addressed relative to the stack
pointer \texttt{SP}, starting at offset \texttt{SP+8} for parameters with
ascending offsets as described for global variables (\texttt{SP} is
reserved for the saved instruction pointer \texttt{IP}, see \ref{The
generation of functions}). Local variables start at offset \texttt{SP-8} in
descending order (\texttt{SP-16} for the second 64 bit variable,
\texttt{SP-24} for the third etc., see table below) in descending order.
Ignoring the sign, the offset relative to SP is still in ascending order,
so the offset calculation method as used for global variables and
parameters can be used.\\ \\
+ \begin{table}[h]
+ \begin{tabular}{llp{2cm}l}
+ \cmidrule{1-2}
+ \textbf{Address} & \textbf{Content} & & \textbf{Source code}\\
+ \cmidrule{1-2}
+ \texttt{SP-0} & Saved \texttt{IP} & & \\
+ \texttt{SP-8} & \texttt{a} & & \texttt{var a uint64;}\\
+ \texttt{SP-16} & \texttt{b} & & \texttt{var b uint64;}\\
+ \texttt{SP-24} & \texttt{c} & & \texttt{var c uint64;}\\
+ \texttt{SP-32} & \texttt{s} (higher 8 bytes) & & \texttt{var s
string;}\\
+ \texttt{SP-40} & \texttt{s} (lower 8 bytes) & & \\
+ \cmidrule{1-2}
+ \end{tabular}
+ \end{table}\\ \\
+ As global and local variables as well as parameters share the same
offset calculation as described above, they can be treated equally with no
change of the offset calculation mechanism. When printing a reference to a
variable address in the output, the relative offset does not need to be
changed, only the reference address (the beginning of the data segment,
\texttt{data}, or \texttt{SP} respectively) and the offset's sign. This
requires the variable's kind (local, global, parameter) to be stored during
code generation until both address and offset are needed. This is done by
introducing a new field named \texttt{Global} to the \texttt{Item} type
(see next section), indicating whether an object is a global or a local
variable or a parameter, respectively.\\
+ Offset calculations within types (p.e. calculating the field offsets
in a struct or an array index) require a slightly different handling.
Global variables as well as parameters can be treated the same way as
explained above as their internal offsets' ascending order corresponds to
their memory layout (ascending addresses). Local variables require a
different calculation as their memory layout (descending addresses)
differs. This is necessary in order to be able to assign global to local
variables and vice verse so that their internal memory layouts correspond
from the programmer's point of view. This is also done by a distinction
based on the item's \texttt{Global} flag as explained above: during code
generation, the internal offset of a local variable has to be calculated by
subtraction instead of addition due to the negative sign of the offset
(also see table above).
+
+ \chapter{Code generation}
+ GoGC emits assembly code in text form based on the Go input files.
This section briefly explains the main features implemented in the code
generating functions of GoGC.
+
+ \section{Register allocation}
+ The target architecture provides 8 general purpose registers
(\texttt{R8}-\texttt{R15}) as well as the registers \texttt{RAX},
\texttt{RBX}, \texttt{RCX} and \texttt{RDX}\cite{int09}. The latter are not
being used by GoGC to store variables as their values may change when
performing arithmetical operations (p.e. \texttt{RAX} and \texttt{RDX} are
always used as the destination registers for multiplications), thus
possibly overwriting values previously stored there.\\
+ GoGC stores a list for every one of the 8 registers currently
free, returning the first free register if required by the code generator.
Whenever a register is no longer required (freed), it will be reinserted
into the "free" list in order to make it available for future use. Due to
the limited amout of registers, the list described is implemented in form
of a bit array in the compiler.
+
+ \section{Generation of arithmetical expressions}
+ As described in \cite{wir96}, code generation for arithmetical
expressions basically relies on an operand stack and delayed code
generation based on \texttt{Items}. For constant operands, constant folding
is applied; variable operands are loaded into a free register in order to
perform arithmetical operations on them.\\
+ GoGC makes use of the capabilities of the target architecture by not
loading constants into registers, thus reducing the number of registers
required. Consider the expression \texttt{a + b} where both \texttt{a} and
\texttt{b} are variables of type \texttt{uint64} with negative offsets 8
and 16 relative to the stack pointer. As the target architecture is able to
perform an operation like \texttt{ADDQ R8, -16(SP)} (add the value at
address \texttt{SP-16} to the register \texttt{R8}), only \texttt{a} needs
to be loaded into a register, whereas \texttt{b} can be directly
incorporated into the instruction itself.\\
+ Multiplication and division on the target architecture both require
special treatment: The multiplication instruction only takes the second
operand and requires the first operand to be in the register
\texttt{RAX}\cite{int09}. Therefore, the first operand has to be loaded
into \texttt{RAX} prior multiplication. The multiplication result is stored
as 128 bit value in \texttt{RDX} (upper 64 bits) and \texttt{RAX} (lower 64
bits). As GoGC does not support data types other than \texttt{byte} and
\texttt{uint64}, the upper 64 bits in \texttt{RDX} are ignored, and the
lower 64 bits are moved to one of the 8 registers to save the result before
another multiplication is being performed. Similarly, division allows for
an 128 bit operand (also in \texttt{RDX} and \texttt{RAX}). As GoGC does
not support 128 bit size data types, \texttt{RDX} is always being zeroed
prior division.\\
+ The addition, substraction and multiplication operations are also
used for offset calculations. Thus, an additional distinction per
\texttt{Item} is required in order to be able to distinguish between
addresses and values stored in registers. As arithmetical operations on
\texttt{byte} and \texttt{uint64} types always operate on a value, the
actual value to be calculated with has to be loaded prior calculation. As
offset calculations always require the address to be loaded into the
register instead of the value, it has to be made sure that the address is
loaded, not the value. In order to distinguish between addresses and values
in registers, the \texttt{A} field of the \texttt{Item} structure is used.
Additionally, the code generation routines for addition and subtraction
have an additional parameter specifying whether to calculate with addresses
or values, issuing the necessary dereferencing operations if required.
+
+ \section{Generation of assignments}
+ As pointer types are supported, type checks in assignments as well
as the assignments themselves get harder to implement as additional cases
have to be dealt with. Additionally, the possible occurrence of the address
operator (\texttt{\&}) on the right hand side of an assignment doubles the
number of cases. The following table \ref{tbl:assigntypes} illustrates the
distinctions made and the code generated for some of the cases allowed by
the EBNF (* denotes pointer types, LHS and RHS are the \texttt{Items} on
the left and right hand side, respectively). For the sake of clearity, only
the cases with a non-pointer type variable \texttt{Item} on the left hand
side and no address operator on the right hand side using \texttt{uint64}
types are shown. The compiler is also able to assign \texttt{byte} values
to one another as well as to \texttt{uint64} types.
+
+ \begin{table}[htb]
+ \begin{tabular}{lll}
+ \toprule
+ \textbf{LHS type} & \textbf{RHS type} & \textbf{Code/Error
generated}\\
+ \midrule
+ Variable & Constant & \texttt{MOVQ \$RHS.A, (LHS.A)}\\
+ Variable & Constant* & Type error\\
+ Variable & Variable & \texttt{MOVQ (RHS.A), R\textit{temp} | MOVQ
R\textit{temp}, (LHS.A)}\\
+ Variable & Variable* & Type error\\
+ Variable & Register with value & \texttt{MOVQ RHS.R, (LHS.A)}\\
+ Variable & Register with value* & Type error\\
+ Variable & Register with address & \texttt{MOVQ (RHS.R), RHS.R |
MOVQ RHS.R, (LHS.A)}\\
+ Variable & Register with address* & Type error\\
+ \bottomrule
+ \end{tabular}
+ \caption{Assignment types}
+ \label{tbl:assigntypes}
+ \end{table}
+
+ String assignments are handled separately as they require 16 bytes
to be assigned. As one register can only hold 8 bytes, a second register
needs to be allocated in order to perform the assignment. Although this may
not be necessary in trivial cases where one string variable is assigned to
another, strings in structures which require offset calculations force the
use of a register when performing the offset calculation and therefore
require a second register to dereference the value of the other 8 bytes. In
order to be able to do this, the \texttt{C} field of the \texttt{Item}
structure is being used as it is not needed for other purposes outside
conditionals.
+
+ \section{Generation of conditional expressions and control structures}
+ In order to achieve condional jumps, GoGC (and thus Go) provides
expressions
+ that allow comparisons (\texttt{==}, \texttt{!=}, \texttt{$>$},
\texttt{$<$},
+ \texttt{$\ge$}, \texttt{$\le$}) and relative operators
(\texttt{\&\&},
+ \texttt{$||$}). The approach how code is generated differs from
\cite{wir96}.
+ Since our output language is text-based Plan9 assembly, there exists
no way
+ to create a fixup chain that could be used to fix conditional jumps
after
+ generating the code. As a result, GoGC creates labels that are then
+ translated into adresses by the Plan9 assembly tools. \\
+
+ Since jumps are always generation after comparisons the code
generation
+ for conditional jumps just needs two instructions. A \texttt{CMP}
instruction
+ for the actual comparison (this instruction is not bound to the
comparison
+ operator) and the conditional jump that takes the evaluates the
registers
+ of the comparison. The jumps that are needed can be seen in table
\ref{tbl:jumps}.
+
+ \begin{table}[htb]
+ \centering
+ \begin{tabular}{ll}
+ \toprule
+ \textbf{Comparisons} & \textbf{Positive Jump} \\
+ \midrule
+ Equal \texttt{==} & \texttt{JE}\\
+ Not equal \texttt{!=} & \texttt{JNE}\\
+ Greater than \texttt{$>$} & \texttt{JG}\\
+ Less than \texttt{$<$} & \texttt{JL}\\
+ Less than or equal \texttt{$\le$} & \texttt{JLE}\\
+ Greater than or equal \texttt{$\ge$} & \texttt{JGE}\\
+ \bottomrule
+ \end{tabular}
+ \caption{Conditional jumps used}
+ \label{tbl:jumps}
+ \end{table}
+
+ The label generation (and thus the resulting labels) can be
summarized as
+ follows:
+ \begin{itemize}
+ \item Each label has a suffix indicating whether it is used by an
+ \texttt{if/else} or \texttt{for} statement.
+ \item Per convinience (Go forces this) programs compiled with GoGC
+ are only allowed to have one statement (or control structure) per
+ line. A side-effect of this limitation is that the addition of
line
+ and column number of the expression into the label guarantees
global
+ uniqueness.
+ \item Furthermore, an expression local counter, representing a
\texttt{true}
+ or \texttt{false} branch is included.
+ \item A simple prefix (used for debugging readability) makes a GoGC
+ label complete.
+ \end{itemize}
+
+ In order to provide common programming constructs that involve
pointer
+ comparisons (see listing \ref{lst:pointer}), GoGC uses
lazy-evaluation.
+
+ \begin{lstlisting}[label=lst:pointer,caption=Pointer comparison]
+if object != nil && object.field ... {
+ \end{lstlisting}
+
+ Lazy-evaluation is provided over multiple levels of expressions using
+ label merging to minimize the overhead. Each top level expression
gets
+ its own stacks for \texttt{true} and \texttt{false} branching.
Further
+ sub-expressions labels (in fact, just their local counters) are then
+ pushed and poped to/from the coresponding stacks. An example
illustrating
+ this need is stated in \ref{lst:lazy}.
+ \begin{lstlisting}[caption=Lazy-evaluation over multiple expression
levels, label=lst:lazy]
+if (done!=1) && (((a<1) && (b<2)) || ((c<3) && (d<4))) { ...
+ \end{lstlisting}
+ While the first \texttt{false} branch has to be generated for the
term
+ $(done!=1)$, further ones are needed for $(a<1)$ and $(c<3)$.
Although these are
+ \texttt{false} branches, they have different levels and result in
different
+ merging points.
+
+ \subsection*{Conditional Jumps}
+ GoGC provides one control structure that can be used for conditional
jumps,
+ namely \texttt{if}/\texttt{else}. While elseif and case statements
could
+ have provided further programming experience, the compiler itself
uses only
+ \texttt{if}. The \texttt{if}/\texttt{else} construct uses the
condional
+ expressions explained above and results in a structure as follows:
+ \begin{table}[hbt]
+ \centering
+ \begin{tabular}{l}
+ \toprule
+ Code generated for expression\\
+ \texttt{If} prolog including possible \texttt{else} jump\\
+ \hspace{0.5cm} \texttt{True} body\\
+ \texttt{Else} header\\
+ \hspace{0.5cm} \texttt{False} body\\
+ Epilog catching \texttt{true} body exit\\
+ \bottomrule
+ \end{tabular}
+ \end{table}
+
+ \subsection*{Loops}
+ GoGC supports only \texttt{for} structures to construct loops,
because
+ Go doesn't offer any other form of loops itself. In order to provide
a more
+ lightweight loop variant, one may skip parts of the \texttt{for}
construct.
+ The language construct is defined as follows:
+ \begin{lstlisting}
+for <initial-assignment> ; <expression> ; <loop-assignment> { ...
+ \end{lstlisting}
+
+ While usually one might use the initial-assignment and the
loop-assignment
+ to control the flow, they can be skipped. In fact, each part may be
skipped
+ to generate a very lightweight \texttt{while(true)} loop. The code
that is
+ usually (using all three clauses) generated has the structure:
+
+ \begin{table}[hbt]
+ \centering
+ \begin{tabular}{l}
+ \toprule
+ \textbf{Code structure}\\
+ \midrule
+ Initial-assignment\\
+ Expression label\\
+ Expression evaluation\\
+ (Jump to body if first iteration)\\
+ Conditional jump to epilog depending on the expression\\
+ Loop-assignment label\\
+ \hspace{0.5cm} Loop-assignment\\
+ Loop body label\\
+ \hspace{0.5cm} Loop body\\
+ Epilog catching exits\\
+ \bottomrule
+ \end{tabular}
+ \end{table}
+
+
+ \section{Generation of functions calls} \label{The generation of
functions}
+ Consider the following example with the current function having 3
local variables -- 2 of type \texttt{uint64} and one of type
\texttt{string} -- calling the function \texttt{foo} which has the
following prototype:
+ \begin{lstlisting}
+func foo(param1 uint64, param2 uint64, param3 string) uint64;
+ \end{lstlisting}
+ In order to be compatible to the Go calling convention, the stack is
organized as follows before calling \texttt{foo}:
+ \begin{table}[h!]
+ \begin{tabular}{ll}
+ \toprule
+ \textbf{Address} & \textbf{Content}\\
+ \midrule
+ \texttt{SP-0} & Saved \texttt{IP}\\
+ \texttt{SP-8} & Local variable 1 (uint64)\\
+ \texttt{SP-16} & Local variable 2 (uint64)\\
+ \texttt{SP-24} & Local variable 3 (string), higher 8 bytes\\
+ \texttt{SP-32} & Local variable 3 (string), lower 8 bytes\\
+ \midrule
+ \texttt{SP-40} & Placeholder for return value of foo\\
+ \texttt{SP-48} & \texttt{param3} of \texttt {foo}, higher 8 bytes\\
+ \texttt{SP-56} & \texttt{param3} of \texttt {foo}, lower 8 bytes\\
+ \texttt{SP-64} & \texttt{param2} of \texttt {foo}\\
+ \texttt{SP-72} & \texttt{param1} of \texttt {foo}\\
+ \bottomrule
+ \end{tabular}
+ \end{table}\\ \\
+ As can be seen, the parameters are pushed in reverse order and share
the address calculation algorithm of local variables (considering the
offsets of the local variables), allowing to reuse the latter for this
purpose. In order to move the parameters to their corresponding positions
on the stack, the offsets are calculated and an assignment statement with
the stack offset on the LHS (as variable \texttt{Item}) is being performed
which allows to reuse the code for assignment generation, including all
type checks and conversions. Optionally, currently used registers are
pushed onto the stack between the local variables and the return value,
yielding an offset correction to be considered when pushing the
parameters.\\
+ When calling \texttt{foo} in the above example, the \texttt{SP} is
first decreased by 72, followed by another implicit decrease of 8 due to
the \texttt{CALL} instruction which pushes the current \texttt{IP} onto the
stack and decreases the \texttt{SP} automatically. The stack is then
prepared for \texttt{foo} to which it appears similar as to the callee,
with the old \texttt{IP} at offset \texttt{SP}, the parameters on positive
offsets relative to \texttt{SP} and the local variables (if any) with
negative offsets.
+ \begin{table}[h!]
+ \begin{tabular}{lll}
+ \toprule
+ \textbf{Address after call} & \textbf{Address before call} &
\textbf{Content}\\
+ \midrule
+ \texttt{SP+40} & \texttt{SP-40} & Placeholder for return value of
foo\\
+ \texttt{SP+32} & \texttt{SP-48} & \texttt{param3} of \texttt
{foo}, higher 8 bytes\\
+ \texttt{SP+24} & \texttt{SP-56} & \texttt{param3} of \texttt
{foo}, lower 8 bytes\\
+ \texttt{SP+16} & \texttt{SP-64} & \texttt{param2} of \texttt
{foo}\\
+ \texttt{SP+8} & \texttt{SP-72} & \texttt{param1} of \texttt {foo}\\
+ \texttt{SP} & -- & \texttt{IP} of callee\\
+ \texttt{SP-8} & -- & Possible local variable of \texttt{foo}\\
+ \bottomrule
+ \end{tabular}
+ \end{table}\\ \\
+ As can be seen, the offsets before and after the call differ by
\texttt{72+8=80} as explained above. GoGC does not use base or frame
pointers, but relies only on the stack pointer to perform all offset
calculations. The return value is always located "after" the other
parameters and can be used as the RHS of an assignment with its known
offset as explained with the parameters above. After the function call, 80
is added to the stack pointer in order to restore the previous stack "view"
for the callee. Optionally saved registered are restored considering their
additional offset in reverse order.\\
+ Internally, a function is represented by a \texttt{TypeDesc}
(compare table \ref{tbl:typedesc}) where the fields represent the functions
parmaeters, including an optional return value at their end. When a
function is being called without prior declaration, the parameter types
have to be derived from the types of the expressions encountered. As the
total number of parameters is unknown before the end function call in the
input file, a marker is inserted in the output code and comments to
indicate that the final offset has yet to be determined. As the offset due
to local variables is known, it is included. Due to the marker which
includes information about the name of the function called, the linker is
able to adapt the unfinished offsets in order to correct them accordingly.\\
+ When functions have been called, but not declared, and then called
again, the type check included in the code generation for assignments is
already effective and detects improper assignment types. However, it is
necessary to extend this check as the first call can p.e. be with a
parameter of type \texttt{byte} and the second call with a parameter of
type \texttt{uint64}. This is allowed, as a \texttt{byte} type represents a
subset of the \texttt{uint64} type, requiring a conversion for the former
in order to assure that the 7 additional bytes are zero. This can be done
by simply extending the type check of the assignment. This also applies to
the return value (as it is treated like a parameter), although it has to be
considered that calls of functions without return value assignments do not
necessarily mean that the function called has no return value. Therefore,
additional checks are necessary, including the check of the return value's
existence and type when the actual function declaration is being made.
+
+ \section{Global variable initialization}
+ Besides the compiled functions from the input file, the code
segment contains a function called main.init which performs the
initialization of global variables. In contrast to local variables which
can be initialized directly at point of their declaration, global variables
need to be initialized before any other methods are called, thus requiring
the main.init function.\\
+ Global variables in general are stored in the data segment, called
\texttt{data} in the output. They are addressed by their corresponding
symbol table offsets relative to the beginning of the data segment. For the
special treatment of string constants, please refer to the next section.
+
+ \section{String constants} \label{String constants}
+ Strings in Go are 16 bytes in size, containing an 8 byte address
(pointer) to its character buffer and an 8 byte length (of which only 4
bytes are used). This makes string length calculations unnecessary and also
explains why strings in Go are read-only and have to be reallocated when
being changed.\\
+ Whenever a string constant is found in the input code, a new byte
array with the string's length is declared and initialized with the
string's characters. Next, another 16 bytes are allocated which represent
the actual string. Using the main.init function as described in the
previous section, the string's length and the previously allocated byte
array address are assigned to the according offsets of the string in the
data segment. When assigning the string constant (or using it as a
parameter), an item representing a data segment variable with the string's
address is used, therefore eliminating the need for any further special
treatment.
+
+ \chapter{Library and run time}
+ In order to be able to perform I/O operations and memory management, a
library called libgogo is implemented which wraps Linux syscalls and
provides an easy to use interface to the GoGC compiler. As GoGC generates
assembly code for 64 bit Linux operating systems and the Go compiler allows
to mix assembly and Go code, the operating system's built-in functions can
be used via syscalls in order to provide the functionality described above.
+
+ \section{I/O syscalls}
+ Besides read and write operations to files (and the console),
exiting the program as well as opening and closing files requires the use
of syscalls. On Linux 64 bit operating systems with Intel architecture,
these syscalls can be invoked by the assembly mnemonic \texttt{SYSCALL}
where the register \texttt{RAX} contains the syscall number defining the
syscall, and the registers \texttt{RDI}, \texttt{RSI} and \texttt{RDX}
contain the first, second and third parameter respectively\cite{var08}.\\
+ The following table \ref{tbl:syscalls} lists the syscalls used by
libgogo, together with the value of \texttt{RAX} representing the syscall
number. The latter were derived from the C constants defined in
\texttt{/usr/src/linux-headers-2.6.32-22/arch/x86/include/asm/unistd\_64.h}
of the current Linux kernel source\cite{var10}. The syscall function
prototypes (for semantics and formal parameters) were derived from the
corresponding Linux man pages (see \cite{var97} and others).
+
+ \begin{table}[htb]
+ \centering
+ \begin{tabular}{ccc}
+ \toprule
+ \textbf{Syscall number (\texttt{RAX})} & \textbf{Syscall function}
& \textbf{Purpose}\\
+ \midrule
+ 0 & \texttt{sys\_read} & Reads from a file\\
+ 1 & \texttt{sys\_write} & Writes to a file\\
+ 2 & \texttt{sys\_open} & Opens a file\\
+ 3 & \texttt{sys\_close} & Closes a file\\
+ 12 & \texttt{sys\_brk} & See next section\\
+ 60 & \texttt{sys\_exit} & Exits the program\\
+ \bottomrule
+ \end{tabular}
+ \caption{Syscalls}
+ \label{tbl:syscalls}
+ \end{table}
+
+ \section{Memory manager}
+ Libgogo provides a very simple memory manager using a bump pointer
which can allocate, but not free memory. By using the
\texttt{sys\_brk}\cite{var97} function, the memory manager expands the data
segment of the running program in steps of 10 KB if necessary in order to
deal with subsequent allocations.\\
+ As the Go compiler used for boot strapping uses a custom memory
manager in its run time environment, the libgogo memory manager and the
GoGC compiler take measures to avoid conflicts with the former. First and
foremost, all implicit and explicit memory allocations in the GoGC compiler
rely on the libgogo memory manager in order to keep the amount of memory
allocated by the Go run time constant. Additionally, the memory manager
does not allocate any memory in the original data segment to not overwrite
any string constants or other information stored there by the Go run time.
This is achieved by directly expanding the data segment during the
initialization of the libgogo memory manager which also allows to store the
first address allocated, thus being able to distinguish between memory
allocated by the libgogo memory manager and memory allocated by the Go run
time.
+
+ \section{String memory management}
+ Based on the memory manager described above, functions to copy and
append strings are implemented in libgogo. As strings in Go are read-only
once they are created (or appended), subsequent appending operands require
the string to be entirely copied to a new memory location first. In order
to avoid this in most cases, the functions handling string appending in
libgogo allocate more memory than needed for the current operation in order
to be able to reuse this memory in subsequent append operations if the
string appended is short enough to fit in the memory already allocated.\\
+ Empirical testing showed that it is most convenient to allocate the
next power of two of the string length required (p.e. 16 if 9 bytes are
initially required). This reduces the number of copy operations and thus
memory consumption by more than a power of 10 for very large strings and
small appended string (which is common appending code output).\\
+ The string manager also has to take care of strings which have been
allocated by the Go run time as those strings don't have any "spare" bytes
left. Thus, a reallocation of memory for these strings is necessary and
cannot be avoided. Subsequent allocations (after the reallocation) can then
be dealt with as described above, leading to the performance gains
mentioned. The distinction between strings allocated by the Go run time and
the libgogo memory manager can be performed easily by comparing the
string's address with the first address available to the libgogo memory
manager as described in the previous section. If the string's address is
smaller, the string is not yet managed by the libgogo memory manager.
+
+ \section{Program parameter determination}
+ Usually, a program's parameters are accessible through \texttt{argc}
and \texttt{argv}, positioned on the stack as function parameters of the
main (entry) function. As the Go compiler used for bootstrapping adds run
time routines which are invoked before the main function, the parameters
cannot be fetched from the stack as their position cannot be determined.
The Go compiler allows to access these parameters using a separate package
(library) which could not be used in order to remain independent of third
party libraries.\\
+ The current approach to fetch parameters requires the activation of
the \texttt{proc} file system in the Linux kernel which is enabled by
default in most Linux distributions\cite{var06}. The \texttt{proc} file
system allows (among other information) to access parameters of all
processes running in the system, including the current process. The
latter's parameters can be through the virtual file
\texttt{/proc/self/cmdline} where \texttt{self} refers to the current
process. The virtual file contains all parameters, separated by zero bytes
and terminated by a sequence of two zero bytes. When parsed, this allows to
access the program's parameters without having to access the stack.
+
+ \chapter{Building / Self-compilation}
+ \label{chpt:building}
+ This section deals with the building process of GoGC and how
self-compilation
+ is achieved.
+
+ \section{Go language tools}
+ Before introducing the compilation procedure it is important to know
how
+ the Go language tools (which are actually Plan9 tools) are organized.
+
+ Each CPU architecture gets a number that is prefixed before a tool.
In
+ GoGC's case this would be \texttt{6}, indicating an AMD64
architecture.
+ The tool suite is then organized into various compilers/linkers:
+ \begin{itemize}
+ \item \texttt{6a} - Assembler for AMD64 architecture (creating
\texttt{*.6}
+ object files)
+ \item \texttt{6g} - Go compiler for AMD64 architecture (creating
\texttt{*.6}
+ object files)
+ \item \texttt{6l} - Linker creating an AMD64 ELF binary out of
object files
+ \end{itemize}
+ Again, the file extensions of the object format indicate the CPU
+ architecture used.
+
+ \section{Boot-strapping}
+ To create the initial compiler that is then used for subsequent
+ compilations, the Go language tools are used. Go uses
\texttt{Makefile}s
+ for defining the appropriate compilation procedure. Basically, three
steps
+ are needed to create the GoGC binary:
+ \begin{enumerate}
+ \item Library compilation - The \texttt{6g} and \texttt{6a} tools
are
+ used to create a single object file containing the library code.
+ \item Compiler compilation - Compile the compiler using
\texttt{6g}.
+ \item Link - Link the compiler object file and the library object
file
+ into an ELF binary using \texttt{6l}.
+ \end{enumerate}
+ At the end of this procedure, an architecture-dependent (AMD64) GoGC
+ compiler has been created.
+
+ \section{Self-compilation}
+ \label{sec:sc}
+ After creating a first bootstrapped version of the compiler, this
one may
+ be used for self-compilation. GoGC is written in the same language it
+ is able to compile to assembly level. Therefore, no further additions
+ or changes have to be made to the source code.
+ The procedure to achieve self-compilation until assembly level is
shown
+ in figure \ref{fig:sc}.
+
+ \begin{figure}
+ \centering
+ \includegraphics[scale=0.4,angle=-90,clip=true,trim=0cm 0cm 3cm
0cm]{files/building}
+ \label{fig:sc}
+ \caption{Self-compilation approach}
+ \end{figure}
+
+ Although GoGC is capable of doing some very basic linking (i.e. copy
+ functions from different files and adjust the symbol table), it is
not
+ possible to use separate compilation during self-compilation. Altough
+ function linking would work, GoGC is not able to handle global
variables
+ that are spread over multiple packages correctly in the linking
process.
+ Thus, the approach is straight-forward and can be summarized by the
following:
+ \begin{enumerate}
+ \item All sources, this includes library, as well as compiler
sources,
+ are compiled in one step. The bootstrapped compiler is used in
compile
+ mode for this step.
+ File ordering does not matter as long as there are no forward
declared global
+ variables involved (where a type has to be known). While
\texttt{*.go}
+ files are compiled, \texttt{*.s} files are treated as assembly
and
+ directly copied into the output.
+ \item The compiled source file (\_gogo\_.sog) is then again
processed by
+ the bootstrapped compiler in the linker mode. This mode is used
to fix
+ offset addresses in the parameter handling of previously forward
declared functions.
+ \item The received file (\_final\_.sog) then contains the compiled
+ compiler in assembly language.
+ \item Finally, this file is used as input for
\texttt{6a}/\texttt{6l} to
+ create a platform-dependent ELF binary. This is not part of the
self-compilation,
+ but necessary to get an executable file.
+ \end{enumerate}
+
+ In order to perform a fixpoint-test, this procedure is used to
generate
+ another instance using the previously compiled GoGC compiler. The
+ fixpoint-test passes and there are no differences in subsequent
compilations.
+
+ \chapter{Testing}
+ In order to test the compiler, a test suite (using \texttt{bash}) has
been
+ constructed that may be used to verify results against an already
existing
+ result set. \\ \\
+ The test suite offers the following functions:
+ \begin{itemize}
+ \item \textbf{newvalids/ackvalids/fullclean} -- These commands are
used to
+ create a new result set as reference for further tests. While
+ \texttt{fullclean} deletes the old set, \texttt{newvalids} is used
to
+ create a new one. After verifying that the compiled output is
correct
+ (by manually checking it), the command \texttt{ackvalids} can be
used to
+ acknowledge the set (resulting in a checksum file).
+ \item \textbf{test/clean} -- \texttt{test} is used to perform a
+ compilation and compare the results against the last valid result
set.
+ In order to do so, checksums of the tests are compared. If they
are not
+ equal, a \texttt{diff} is printed to the user. \texttt{Clean}
deletes
+ all temporary files.
+ \end{itemize}
+ Listing \ref{lst:test} shows the usage and an example output of the
testsuite.
+\lstset{
+language=bash
+}
+ \begin{lstlisting}[caption=Testsuite example,label=lst:test]
+$ ./testsuite test
+
+>>> Performing internal checks
+
+Checking for sha256sum tool... ok
+Checking for gogo compiler... ok
+Checking for tests... ok
+
+>>> Checking whether an acknowledged resultset exists
+
+>>> Generating tests
+Checking for tmp... creating it
+
+>>> Performing quick check
+* Checksums matched. Everything seems fine
+ \end{lstlisting}
+ \bibliographystyle{alpha}
+ \bibliography{gogo}
+
+\end{document}
=======================================
--- /docs/latex/Makefile Tue Aug 17 18:24:43 2010
+++ /dev/null
@@ -1,8 +0,0 @@
-all:
- pdflatex gogo.tex
- bibtex gogo
- pdflatex gogo.tex
- pdflatex gogo.tex
-
-clean:
- rm -rf *.bbl *.log *.toc *.aux *.out *.blg *.pdf
=======================================
--- /docs/latex/files/building.pdf Tue Aug 17 18:24:43 2010
+++ /dev/null
Binary file, no diff available.
=======================================
--- /docs/latex/gogo.bib Wed Jun 9 09:43:02 2010
+++ /dev/null
@@ -1,71 +0,0 @@
-@Book{
- wir96,
- author = {{Wirth, N.}},
- title = {{Compiler Construction}},
- publisher = {{Addison-Wesley}},
- year = {1996},
- lanuage = {english}
-}
-
-@Misc{
- goo10,
- author = {{Google Inc.}},
- title = {{The Go Programming Language Specification}},
- howpublished = {\url{
http://golang.org/doc/go_spec.html} (4.6.2010)},
- year = {2010},
- language = {english}
-}
-
-@Misc{
- pik00,
- author = {{Pike, R.}},
- title = {{A Manual for the Plan 9 assembler}},
- howpublished = {\url{
http://doc.cat-v.org/plan_9/4th_edition/papers/asm}
(4.6.2010)},
- year = {2000},
- language = {english}
-}
-
-@Misc{
- int09,
- author = {{Intel Inc.}},
- title = {{Intel 64 and IA-32 Architectures Software Developer's Manual,
Volume 2A: Instruction Set Reference, A-M}},
- howpublished =
{\url{
http://www.intel.com/products/processor/manuals/index.htm}
(9.6.2010)},
- year = {2009},
- language = {english}
-}
-
-@Misc{
- var97,
- author = {{Various}},
- title = {{brk(2) -- Linux man page}},
- howpublished = {\url{
http://linux.die.net/man/2/brk} (9.6.2010)},
- year = {1997},
- language = {english}
-}
-
-@Misc{
- var10,
- author = {{Various}},
- title = {{The Linux Kernel}},
- howpublished = {\url{
http://www.kernel.org} (9.6.2010)},
- year = {2010},
- language = {english}
-}
-
-@Misc{
- var08,
- author = {{Various}},
- title = {{syscalls(2) -- Linux man page}},
- howpublished = {\url{
http://linux.die.net/man/2/syscalls} (9.6.2010)},
- year = {2008},
- language = {english}
-}
-
-@Misc{
- var06,
- author = {{Various}},
- title = {{proc(5) -- Linux man page}},
- howpublished = {\url{
http://linux.die.net/man/5/proc} (9.6.2010)},
- year = {2006},
- language = {english}
-}
=======================================
--- /docs/latex/gogo.tex Tue Aug 17 09:58:38 2010
+++ /dev/null
@@ -1,682 +0,0 @@
-\documentclass[a4paper]{scrartcl}
-
-\let\chapter\section
-\let\section\subsection
-\let\subsection\subsubsection
-\let\subsubsection\paragraph
-\let\paragraph\subparagraph
-\let\subparagraph\undefined
-
-\usepackage{booktabs}
-\usepackage[usenames,dvipsnames]{color}
-\usepackage[latin1]{inputenc}
-\usepackage{listings}
-\usepackage[english]{babel}
-\usepackage[pdftex,plainpages=false,pdfpagelabels,
- hyperfootnotes=false]{hyperref}
-\hypersetup{pdftitle={GoGC -- A Go compiler written in Go},
- pdfauthor={Michael Lippautz, Andreas Unterweger},
- pdfsubject={GoGC},pdfkeywords={Go,Compiler,GoGC}}
-\usepackage{graphicx}
-
-\definecolor{lightgray}{RGB}{250,250,250}
-
-\lstset{
- basicstyle=\small,
- frame=lines,
- backgroundcolor=\color{lightgray}
-}
-
-\title{GoGC\\ \large{A Go compiler written in Go}}
-\author{
- Michael~Lippautz \\ \normalsize{\
texttt{michael....@sbg.ac.at}}
- \and
- Andreas~Unterweger \\ \normalsize{\
texttt{andreas.u...@sbg.ac.at}}
-}
-
-\date{\today}
-
-\begin{document}
- \maketitle
- \tableofcontents
-
- \chapter{Introduction}
- GoGC is a self-compiling (see section \ref{chpt:building}) Go compiler
- written in Go which implements scanning, parsing and code generation
for a
- subset of the Go language \cite{goo10}. It is mostly compatible with
the Go
- compiler available at \cite{goo10} and outputs valid Plan9 assembly
code
- which can be assembled by the latter as well as the Plan9 assembly
tools
- \texttt{6a} and \texttt{6l}\cite{pik00}.\\
-
-
- \chapter{Input language}
- Go is a programming language developed by Google, based on a C like
syntax and fully specified in \cite{goo10}. The input language follows the
one defined by Go. This results in programs being able to be compiled by
the official Go compilers and GoGC.
-
- \section{Some differences to Go}
- \begin{enumerate}
- \item GoGC only provides only a \textbf{very} basic featureset.
Expect
- every advanced and interesting feature to be missing.
- \item GoGC forces the usage of semicolons at the end of statements,
- while in actual Go this token is optional. This restriction was
made
- to make parsing easier.
- \item Go is fully Unicode compatible, while GoGC uses ASCII
characters only.
- \item Simplified expressions, following Wirth's
defintions\cite{wir96}.
- \end{enumerate}
-
- \section{EBNF}
- \label{sec:ebnf}
- The following section deals with the input language specification in
- EBNF form. Additionally to the specification below, GoGC also allows
- source code comments following the C++ multiline
style(\texttt{/* ... */})
- and the C inline style (\texttt{//}).
-
- \subsection*{Atoms}
- The following listing describes the basic atoms that are possible
in
- GoGC programs.
- \begin{lstlisting}[caption=Atoms]
-single_char = CHR(32)|...|CHR(127).
-char = "'" single_char "'".
-string = """ {single_char} """.
-
-digit = "0"|...|"9".
-integer = digit {digit}.
-
-letter = "a"|...|"z"|"A"|...|"Z"|"_".
-identifier = letter { letter | digit }.
-selector = { "." identifier
- | "[" (integer | identifier selector) "]" }.
- \end{lstlisting}
-
- \subsection*{Expressions}
- Although not as expressive as the ones from Go, these rules define
expressions that have comparisons, relations and arithmetical terms.
-
- \begin{lstlisting}[caption=Expressions]
-cmp_op = ">" | "<" | ">=" | "<=" | "==" | "!=".
-unary_arith_op = "+" | "-".
-binary_arith_op = "*" | "/" .
-
-factor = identifier selector | integer | char | string
- | "(" expression ")" | "!" factor.
-term = factor { (binary_arith_op | "&&") factor}.
-simple_expression = [ unary_arith_op ] term
- { (unary_arith_op | "||") term }.
-expression = "&" identifier selector
- | simple_expression [ cmp_op simple_expression ].
- \end{lstlisting}
-
- \subsection*{Types and Variable Declarations}
-
- \begin{lstlisting}[caption=Types]
-type = ([ "[" integer "]" ] identifier | "uint64" | "byte")
- | "string".
-var_decl = "var" identifier type [ "=" expression ] ";".
-var_decl_list = { var_decl }
- \end{lstlisting}
-
- \subsection*{Structs}
-
- \begin{lstlisting}[caption=Structs]
-struct_var_decl = identifier type ";".
-struct_var_decl_list = { struct_var_decl }.
-struct_decl = "type" identifier "struct" "{"
- struct_var_decl_list "}" ";".
-struct_decl_list = { struct_decl }.
- \end{lstlisting}
-
- \subsection*{Statements}
-
- \begin{lstlisting}[caption=Statements]
-package_stmt = "package" identifier ";".
-import_stmt = "import" string.
-import_stmt_list = { import_stmt }.
-
-stmt_sequence = { stmt }
-stmt = assignment ";" | function_call_stmt ";" | if_stmt
- | for_stmt | ";".
-
-assignment = identifier selector "=" expression
-if_stmt = "if" expression "{" stmt_sequence "}" [ else_stmt ].
-else_stmt = "else" "{" stmt_sequence "}".
-for_stmt = "for" [assignment] ";" [expression] ";" [assignment]
- "{" stmt_sequence "}".
- \end{lstlisting}
-
- \subsection*{Functions}
-
- \begin{lstlisting}[caption=Functions]
-expression_list = expression { "," expression }.
-function_call = "(" [expression_list] ")".
-function_call_stmt = identifier selector function_call.
-
-identifier_type = identifier [ "*" ] type.
-identifier_type_list = [ identifier_type
- { "," identifier_type } ].
-func_decl_head = "func" identifier "(" identifier_type_list ")" [type].
-func_decl = "{" var_decl_list stmt_sequence
- ["return" expression ";"] "}".
-func_decl_raw = ";".
-func_decl_list = { func_decl_head (func_decl | func_decl_raw)
- \end{lstlisting}
-
- \subsection*{The GoGC Program}
- Finally, the main program structure is defined by
\texttt{go\_program}. The sequence of the various program parts has been
forced to the following to make parsing easier.
-
- \begin{lstlisting}[caption=GoGC Program]
-go_program = package_stmt import_stmt_list struct_decl_list
- var_decl_list func_decl_list.
- \end{lstlisting}
-
-
- \chapter{Output language}
- The output language is Plan-9 assembler \cite{pik00}. It is a modified
version of 64 bit assembly for Intel x86 processors with AT\&T syntax that
has been created by Bell Labs to be used in their compiler and assembler
collection.
-
- \section{Assembly output}
- GoGC creates an output file with assembly instructions and comments
using mnemonics for op codes and operands/registers which means that it
outputs in text form, not in binary form. Thereforce, an assembler is
needed to process the output in order to make it executable. Like the Go
compiler, GoGC relies on \texttt{6a} and \texttt{6l} of the Plan9 tools in
order to acomplish this\cite{pik00}.\\
- The assembly output consists basically of three sections: the data
segment, the initialization segment and the code segment. GoGC's assembly
output framework provides basic output routines which make it possible to
switch between those three segments. Whereas the data segment is used to
reserve space for global variables and strings in the data segment, the
initialization segment and the code segment contain the code for global
variable initialization and the functions from the input, respectively. All
other functions (code generation for arithmetical expressions etc.) rely on
the assembly output framework which is also able to place comments with the
corresponding input file name and line number for debugging purposes in the
output file.
-
- \chapter{Scanner / Parser}
- The scanner is basically the provider of tokens that are used by the
parser
- to process the code. In order to generate these tokens, the scanner
reads
- the file character by character. If a sequence is known, it converts
this
- sequence of characters into the corresponding token. Tokens generated
this
- way are called simple tokens, as they can be generated right away. For
- instance, the sequence \textit{'A'} can be directly converted into a
token
- representing the byte value 65. \\
-
-
-
- Before providing a token to the parser, the scanner may convert such
- simple tokens one more time. These complex tokens are generated from
simple
- ones that represent \texttt{identifiers}. \texttt{Identifiers} are
compared to a
- predefined list of keywords. If a keyword matches a token value, the
token
- is converted to the one representing the keyword. Table
\ref{tbl:tokens}
- lists some of these tokens.
-
- \begin{table}[htb]
- \centering
- \begin{tabular}{ll}
- \toprule
- Simple tokens & \texttt{\&\&}, \texttt{+}, \texttt{-},
\texttt{\{}, \texttt{\}}, \texttt{$($}, \texttt{$)$}, \dots \\
- Complex tokens & \texttt{for}, \texttt{if}, \texttt{else},
\texttt{func}, \texttt{type} \\
- \bottomrule
- \end{tabular}
- \caption{Token examples}
- \label{tbl:tokens}
- \end{table}
-
- The scanner also implements a very simple escaping mechanism that
allows
- sequences like \textit{'\textbackslash n'} to be used in strings. \\
- Comments can be written as \textit{/* ... */} blocks or
- \textit{\textbackslash \textbackslash} until the line ending, like in
C/C++.
- \\ \\
- The parser then takes these tokens and represents the language defined
by
- the EBNF from section \ref{sec:ebnf}. The parser is basically
implemented
- as LL1 like in \cite{wir96}, with one minor difference. In order to be
- compatible with Go it was necesarry to include one namespace hierachy
that
- is represented by packages. Since this name scope is prefixed
- using \texttt{package.}, the parser needs a lookup of three (LL3)in
this
- case.
-
- \chapter{Symbol table}
- In order to be able to lookup local and global variable names as well
as function names, a symbol table is required. Based on \cite{wir96},
object and type descriptors were used, each containing the information
required for lookup and code generation. Object descriptors are used to
store information about variables and parameters whereas type descriptors
are used to store information about types and functions.\\
- The following tables \ref{tbl:objectdesc} and \ref{tbl:typedesc}
summarize the fields of the object and type descriptors and their
respective purpose. Some fields had to be added in order to support forward
declarations and the distinction between values and pointers.
- \begin{table}[htb]
- \centering
- \begin{tabular}{lcl}
- \toprule
- \textbf{Field} & \textbf{Type} & \textbf{Purpose}\\
- \midrule
- Name & \texttt{string} & The object's name\\
- PackageName & \texttt{string} & The object's package (Go name
space)\\
- Class & \texttt{uint64} & The descriptors's kind (variable, field,
parameter)\\
- ObjType & \texttt{*TypeDesc} & The object's type\\
- PtrType & \texttt{uint64} & If 1, the object's type is
\texttt{*ObjType}; if 0, \texttt{ObjType}\\
- Next & \texttt{*ObjType} & Next object (linked list)\\
- \bottomrule
- \end{tabular}
- \caption{ObjectDesc}
- \label{tbl:objectdesc}
- \end{table}
-
- \begin{table}[htb]
- \centering
- \begin{tabular}{lc p{0.6\textwidth}}
- \toprule
- \textbf{Field} & \textbf{Type} & \textbf{Purpose}\\
- \midrule
- Name & \texttt{string} & The type's/function's name\\
- PackageName & \texttt{string} & The type's/function's package (Go
name space)\\
- ForwardDecl & \texttt{uint64} & If 1, the type/function has not
yet been fully delcared/implemented\\
- Form & \texttt{uint64} & The descriptor's kind (simple type, array
type, struct type, function)\\
- Len & \texttt{uint64} & For simple types: type size in bytes, for
arrays: array size\\
- Fields & \texttt{*ObjDesc} & For struct types: struct fields, for
functions: function parameters\\
- Base & \texttt{*TypeDesc} & For array types: the array base type\\
- Next & \texttt{*TypeDesc} & Next type/function (linked list)\\
- \bottomrule
- \end{tabular}
- \caption{TypeDesc}
- \label{tbl:typedesc}
- \end{table}
-
- For both global and function-local symbol tables the build-up and
lookup is integrated into the parser. Whenever sufficient information
(variable name, function name, type name; optionally preceeded by a package
name) is encountered, a lookup in the symbol table is issued. Declarations
issue new symbol table entries with the corresponding descriptor properties
as described above.\\
- Forward declarations are currently only supported for type pointers
(as pointers are always 64 bits in size) and functions (as the affected
offsets can be fixed by the linker if necessary). Whenever supported
forward declarations are encountered, a new symbol table entry is created
with \texttt{ForwardDecl} set to 1. Forward declared function can then be
called, although forward declared type pointers cannot be dereferred until
the size of the type they are pointing to is known (\texttt{ForwardDecl} is
0). When forward declared functions are implemented, the corresponding
symbol table entry is modified (\texttt{ForwardDecl} is set to 0) instead
of creating a new one.
-
- \section{Supported data types}
- GoGC supports 4 built-in value types and the declaration of new
struct and array types as well as pointers to value, struct and array
types. The 4 built-in data types are based on the data types supported by
the Go compiler and form a minimal subset of them in order to perform basic
integer and string operations. The following table \ref{tbl:types} lists
the built-in value types, together with their purpose and size.
-
- \begin{table}[htb]
- \centering
- \begin{tabular}{cc p{0.5\textwidth}}
- \toprule
- \textbf{Type} & \textbf{Size} & \textbf{Purpose}\\
- \midrule
- \texttt{uint64} & 8 bytes (64 bits) & Unsigned integer with the
target platform's register size\\
- \texttt{byte} & 1 byte (8 bits) & Single ASCII character or
unsigned 8 bit integer value\\
- \texttt{string} & 16 bytes (see section \ref{String constants}) &
Character sequences\\
- \texttt{bool} & 8 bytes (64 bits) & Internal type used for
comparisions and jumps\\
- \bottomrule
- \end{tabular}
- \caption{Built-in types}
- \label{tbl:types}
- \end{table}
-
- \section{Local variables and offset calculations}
- In order to be able to distinguish between parameters, local and
global variables, a global and a local symbol table as well the function's
parameters as third, virtual symbol table are used. Local variables hide
global variables of the same name by performing the symbol table lookup for
local variables and parameters first and returning the first match if there
is any.\\
- The memory layout for local and global variables as well as
parameters is equal: the object's offset address contains the first 64 bits
of the object, the next highest address (offset address plus 64 bits)
contains the next 64 bits etc. All local and global variable offset
addresses are 64 bit aligned. The offset of an object can be calculated by
summing the aligned sizes of its predecessors in the corresponding variable
list. Doing this, it has to be taken into consideration that pointers
always occupy 8 bytes (64 bits), regardless of the type they are actually
pointing to.\\
- Global variables start at offset 0 of the data segment, referred to
as \texttt{data+0} in the output. Subsequent global variables use ascending
offsets as described above (p.e. referred to as \texttt{data+8} for offset
8). Local variables and parameters are addressed relative to the stack
pointer \texttt{SP}, starting at offset \texttt{SP+8} for parameters with
ascending offsets as described for global variables (\texttt{SP} is
reserved for the saved instruction pointer \texttt{IP}, see \ref{The
generation of functions}). Local variables start at offset \texttt{SP-8} in
descending order (\texttt{SP-16} for the second 64 bit variable,
\texttt{SP-24} for the third etc., see table below) in descending order.
Ignoring the sign, the offset relative to SP is still in ascending order,
so the offset calculation method as used for global variables and
parameters can be used.\\ \\
- \begin{table}[h]
- \begin{tabular}{llp{2cm}l}
- \cmidrule{1-2}
- \textbf{Address} & \textbf{Content} & & \textbf{Source code}\\
- \cmidrule{1-2}
- \texttt{SP-0} & Saved \texttt{IP} & & \\
- \texttt{SP-8} & \texttt{a} & & \texttt{var a uint64;}\\
- \texttt{SP-16} & \texttt{b} & & \texttt{var b uint64;}\\
- \texttt{SP-24} & \texttt{c} & & \texttt{var c uint64;}\\
- \texttt{SP-32} & \texttt{s} (higher 8 bytes) & & \texttt{var s
string;}\\
- \texttt{SP-40} & \texttt{s} (lower 8 bytes) & & \\
- \cmidrule{1-2}
- \end{tabular}
- \end{table}\\ \\
- As global and local variables as well as parameters share the same
offset calculation as described above, they can be treated equally with no
change of the offset calculation mechanism. When printing a reference to a
variable address in the output, the relative offset does not need to be
changed, only the reference address (the beginning of the data segment,
\texttt{data}, or \texttt{SP} respectively) and the offset's sign. This
requires the variable's kind (local, global, parameter) to be stored during
code generation until both address and offset are needed. This is done by
introducing a new field named \texttt{Global} to the \texttt{Item} type
(see next section), indicating whether an object is a global or a local
variable or a parameter, respectively.\\
- Offset calculations within types (p.e. calculating the field offsets
in a struct or an array index) require a slightly different handling.
Global variables as well as parameters can be treated the same way as
explained above as their internal offsets' ascending order corresponds to
their memory layout (ascending addresses). Local variables require a
different calculation as their memory layout (descending addresses)
differs. This is necessary in order to be able to assign global to local
variables and vice verse so that their internal memory layouts correspond
from the programmer's point of view. This is also done by a distinction
based on the item's \texttt{Global} flag as explained above: during code
generation, the internal offset of a local variable has to be calculated by
subtraction instead of addition due to the negative sign of the offset
(also see table above).
-
- \chapter{Code generation}
- GoGC emits assembly code in text form based on the Go input files.
This section briefly explains the main features implemented in the code
generating functions of GoGC.
-
- \section{Register allocation}
- The target architecture provides 8 general purpose registers
(\texttt{R8}-\texttt{R15}) as well as the registers \texttt{RAX},
\texttt{RBX}, \texttt{RCX} and \texttt{RDX}\cite{int09}. The latter are not
being used by GoGC to store variables as their values may change when
performing arithmetical operations (p.e. \texttt{RAX} and \texttt{RDX} are
always used as the destination registers for multiplications), thus
possibly overwriting values previously stored there.\\
- GoGC stores a list for every one of the 8 registers currently
free, returning the first free register if required by the code generator.
Whenever a register is no longer required (freed), it will be reinserted
into the "free" list in order to make it available for future use. Due to
the limited amout of registers, the list described is implemented in form
of a bit array in the compiler.
-
- \section{Generation of arithmetical expressions}
- As described in \cite{wir96}, code generation for arithmetical
expressions basically relies on an operand stack and delayed code
generation based on \texttt{Items}. For constant operands, constant folding
is applied; variable operands are loaded into a free register in order to
perform arithmetical operations on them.\\
- GoGC makes use of the capabilities of the target architecture by not
loading constants into registers, thus reducing the number of registers
required. Consider the expression \texttt{a + b} where both \texttt{a} and
\texttt{b} are variables of type \texttt{uint64} with negative offsets 8
and 16 relative to the stack pointer. As the target architecture is able to
perform an operation like \texttt{ADDQ R8, -16(SP)} (add the value at
address \texttt{SP-16} to the register \texttt{R8}), only \texttt{a} needs
to be loaded into a register, whereas \texttt{b} can be directly
incorporated into the instruction itself.\\
- Multiplication and division on the target architecture both require
special treatment: The multiplication instruction only takes the second
operand and requires the first operand to be in the register
\texttt{RAX}\cite{int09}. Therefore, the first operand has to be loaded
into \texttt{RAX} prior multiplication. The multiplication result is stored
as 128 bit value in \texttt{RDX} (upper 64 bits) and \texttt{RAX} (lower 64
bits). As GoGC does not support data types other than \texttt{byte} and
\texttt{uint64}, the upper 64 bits in \texttt{RDX} are ignored, and the
lower 64 bits are moved to one of the 8 registers to save the result before
another multiplication is being performed. Similarly, division allows for
an 128 bit operand (also in \texttt{RDX} and \texttt{RAX}). As GoGC does
not support 128 bit size data types, \texttt{RDX} is always being zeroed
prior division.\\
- The addition, substraction and multiplication operations are also
used for offset calculations. Thus, an additional distinction per
\texttt{Item} is required in order to be able to distinguish between
addresses and values stored in registers. As arithmetical operations on
\texttt{byte} and \texttt{uint64} types always operate on a value, the
actual value to be calculated with has to be loaded prior calculation. As
offset calculations always require the address to be loaded into the
register instead of the value, it has to be made sure that the address is
loaded, not the value. In order to distinguish between addresses and values
in registers, the \texttt{A} field of the \texttt{Item} structure is used.
Additionally, the code generation routines for addition and subtraction
have an additional parameter specifying whether to calculate with addresses
or values, issuing the necessary dereferencing operations if required.
-
- \section{Generation of assignments}
- As pointer types are supported, type checks in assignments as well
as the assignments themselves get harder to implement as additional cases
have to be dealt with. Additionally, the possible occurrence of the address
operator (\texttt{\&}) on the right hand side of an assignment doubles the
number of cases. The following table \ref{tbl:assigntypes} illustrates the
distinctions made and the code generated for some of the cases allowed by
the EBNF (* denotes pointer types, LHS and RHS are the \texttt{Items} on
the left and right hand side, respectively). For the sake of clearity, only
the cases with a non-pointer type variable \texttt{Item} on the left hand
side and no address operator on the right hand side using \texttt{uint64}
types are shown. The compiler is also able to assign \texttt{byte} values
to one another as well as to \texttt{uint64} types.
-
- \begin{table}[htb]
- \begin{tabular}{lll}
- \toprule
- \textbf{LHS type} & \textbf{RHS type} & \textbf{Code/Error
generated}\\
- \midrule
- Variable & Constant & \texttt{MOVQ \$RHS.A, (LHS.A)}\\
- Variable & Constant* & Type error\\
- Variable & Variable & \texttt{MOVQ (RHS.A), R\textit{temp} | MOVQ
R\textit{temp}, (LHS.A)}\\
- Variable & Variable* & Type error\\
- Variable & Register with value & \texttt{MOVQ RHS.R, (LHS.A)}\\
- Variable & Register with value* & Type error\\
- Variable & Register with address & \texttt{MOVQ (RHS.R), RHS.R |
MOVQ RHS.R, (LHS.A)}\\
- Variable & Register with address* & Type error\\
- \bottomrule
- \end{tabular}
- \caption{Assignment types}
- \label{tbl:assigntypes}
- \end{table}
-
- String assignments are handled separately as they require 16 bytes
to be assigned. As one register can only hold 8 bytes, a second register
needs to be allocated in order to perform the assignment. Although this may
not be necessary in trivial cases where one string variable is assigned to
another, strings in structures which require offset calculations force the
use of a register when performing the offset calculation and therefore
require a second register to dereference the value of the other 8 bytes. In
order to be able to do this, the \texttt{C} field of the \texttt{Item}
structure is being used as it is not needed for other purposes outside
conditionals.
-
- \section{Generation of conditional expressions and control structures}
- In order to achieve condional jumps, GoGC (and thus Go) provides
expressions
- that allow comparisons (\texttt{==}, \texttt{!=}, \texttt{$>$},
\texttt{$<$},
- \texttt{$\ge$}, \texttt{$\le$}) and relative operators
(\texttt{\&\&},
- \texttt{$||$}). The approach how code is generated differs from
\cite{wir96}.
- Since our output language is text-based Plan9 assembly, there exists
no way
- to create a fixup chain that could be used to fix conditional jumps
after
- generating the code. As a result, GoGC creates labels that are then
- translated into adresses by the Plan9 assembly tools. \\
-
- Since jumps are always generation after comparisons the code
generation
- for conditional jumps just needs two instructions. A \texttt{CMP}
instruction
- for the actual comparison (this instruction is not bound to the
comparison
- operator) and the conditional jump that takes the evaluates the
registers
- of the comparison. The jumps that are needed can be seen in table
\ref{tbl:jumps}.
-
- \begin{table}[htb]
- \centering
- \begin{tabular}{ll}
- \toprule
- \textbf{Comparisons} & \textbf{Positive Jump} \\
- \midrule
- Equal \texttt{==} & \texttt{JE}\\
- Not equal \texttt{!=} & \texttt{JNE}\\
- Greater than \texttt{$>$} & \texttt{JG}\\
- Less than \texttt{$<$} & \texttt{JL}\\
- Less than or equal \texttt{$\le$} & \texttt{JLE}\\
- Greater than or equal \texttt{$\ge$} & \texttt{JGE}\\
- \bottomrule
- \end{tabular}
- \caption{Conditional jumps used}
- \label{tbl:jumps}
- \end{table}
-
- The label generation (and thus the resulting labels) can be
summarized as
- follows:
- \begin{itemize}
- \item Each label has a suffix indicating whether it is used by an
- \texttt{if/else} or \texttt{for} statement.
- \item Per convinience (Go forces this) programs compiled with GoGC
- are only allowed to have one statement (or control structure) per
- line. A side-effect of this limitation is that the addition of
line
- and column number of the expression into the label guarantees
global
- uniqueness.
- \item Furthermore, an expression local counter, representing a
\texttt{true}
- or \texttt{false} branch is included.
- \item A simple prefix (used for debugging readability) makes a GoGC
- label complete.
- \end{itemize}
-
- In order to provide common programming constructs that involve
pointer
- comparisons (see listing \ref{lst:pointer}), GoGC uses
lazy-evaluation.
-
- \begin{lstlisting}[label=lst:pointer,caption=Pointer comparison]
-if object != nil && object.field ... {
- \end{lstlisting}
-
- Lazy-evaluation is provided over multiple levels of expressions using
- label merging to minimize the overhead. Each top level expression
gets
- its own stacks for \texttt{true} and \texttt{false} branching.
Further
- sub-expressions labels (in fact, just their local counters) are then
- pushed and poped to/from the coresponding stacks. An example
illustrating
- this need is stated in \ref{lst:lazy}.
- \begin{lstlisting}[caption=Lazy-evaluation over multiple expression
levels, label=lst:lazy]
-if (done!=1) && (((a<1) && (b<2)) || ((c<3) && (d<4))) { ...
- \end{lstlisting}
- While the first \texttt{false} branch has to be generated for the
term
- $(done!=1)$, further ones are needed for $(a<1)$ and $(c<3)$.
Although these are
- \texttt{false} branches, they have different levels and result in
different
- merging points.
-
- \subsection*{Conditional Jumps}
- GoGC provides one control structure that can be used for conditional
jumps,
- namely \texttt{if}/\texttt{else}. While elseif and case statements
could
- have provided further programming experience, the compiler itself
uses only
- \texttt{if}. The \texttt{if}/\texttt{else} construct uses the
condional
- expressions explained above and results in a structure as follows:
- \begin{table}[hbt]
- \centering
- \begin{tabular}{l}
- \toprule
- Code generated for expression\\
- \texttt{If} prolog including possible \texttt{else} jump\\
- \hspace{0.5cm} \texttt{True} body\\
- \texttt{Else} header\\
- \hspace{0.5cm} \texttt{False} body\\
- Epilog catching \texttt{true} body exit\\
- \bottomrule
- \end{tabular}
- \end{table}
-
- \subsection*{Loops}
- GoGC supports only \texttt{for} structures to construct loops,
because
- Go doesn't offer any other form of loops itself. In order to provide
a more
- lightweight loop variant, one may skip parts of the \texttt{for}
construct.
- The language construct is defined as follows:
- \begin{lstlisting}
-for <initial-assignment> ; <expression> ; <loop-assignment> { ...
- \end{lstlisting}
-
- While usually one might use the initial-assignment and the
loop-assignment
- to control the flow, they can be skipped. In fact, each part may be
skipped
- to generate a very lightweight \texttt{while(true)} loop. The code
that is
- usually (using all three clauses) generated has the structure:
-
- \begin{table}[hbt]
- \centering
- \begin{tabular}{l}
- \toprule
- \textbf{Code structure}\\
- \midrule
- Initial-assignment\\
- Expression label\\
- Expression evaluation\\
- (Jump to body if first iteration)\\
- Conditional jump to epilog depending on the expression\\
- Loop-assignment label\\
- \hspace{0.5cm} Loop-assignment\\
- Loop body label\\
- \hspace{0.5cm} Loop body\\
- Epilog catching exits\\
- \bottomrule
- \end{tabular}
- \end{table}
-
-
- \section{Generation of functions calls} \label{The generation of
functions}
- Consider the following example with the current function having 3
local variables -- 2 of type \texttt{uint64} and one of type
\texttt{string} -- calling the function \texttt{foo} which has the
following prototype:
- \begin{lstlisting}
-func foo(param1 uint64, param2 uint64, param3 string) uint64;
- \end{lstlisting}
- In order to be compatible to the Go calling convention, the stack is
organized as follows before calling \texttt{foo}:
- \begin{table}[h!]
- \begin{tabular}{ll}
- \toprule
- \textbf{Address} & \textbf{Content}\\
- \midrule
- \texttt{SP-0} & Saved \texttt{IP}\\
- \texttt{SP-8} & Local variable 1 (uint64)\\
- \texttt{SP-16} & Local variable 2 (uint64)\\
- \texttt{SP-24} & Local variable 3 (string), higher 8 bytes\\
- \texttt{SP-32} & Local variable 3 (string), lower 8 bytes\\
- \midrule
- \texttt{SP-40} & Placeholder for return value of foo\\
- \texttt{SP-48} & \texttt{param3} of \texttt {foo}, higher 8 bytes\\
- \texttt{SP-56} & \texttt{param3} of \texttt {foo}, lower 8 bytes\\
- \texttt{SP-64} & \texttt{param2} of \texttt {foo}\\
- \texttt{SP-72} & \texttt{param1} of \texttt {foo}\\
- \bottomrule
- \end{tabular}
- \end{table}\\ \\
- As can be seen, the parameters are pushed in reverse order and share
the address calculation algorithm of local variables (considering the
offsets of the local variables), allowing to reuse the latter for this
purpose. In order to move the parameters to their corresponding positions
on the stack, the offsets are calculated and an assignment statement with
the stack offset on the LHS (as variable \texttt{Item}) is being performed
which allows to reuse the code for assignment generation, including all
type checks and conversions. Optionally, currently used registers are
pushed onto the stack between the local variables and the return value,
yielding an offset correction to be considered when pushing the
parameters.\\
- When calling \texttt{foo} in the above example, the \texttt{SP} is
first decreased by 72, followed by another implicit decrease of 8 due to
the \texttt{CALL} instruction which pushes the current \texttt{IP} onto the
stack and decreases the \texttt{SP} automatically. The stack is then
prepared for \texttt{foo} to which it appears similar as to the callee,
with the old \texttt{IP} at offset \texttt{SP}, the parameters on positive
offsets relative to \texttt{SP} and the local variables (if any) with
negative offsets.
- \begin{table}[h!]
- \begin{tabular}{lll}
- \toprule
- \textbf{Address after call} & \textbf{Address before call} &
\textbf{Content}\\
- \midrule
- \texttt{SP+40} & \texttt{SP-40} & Placeholder for return value of
foo\\
- \texttt{SP+32} & \texttt{SP-48} & \texttt{param3} of \texttt
{foo}, higher 8 bytes\\
- \texttt{SP+24} & \texttt{SP-56} & \texttt{param3} of \texttt
{foo}, lower 8 bytes\\
- \texttt{SP+16} & \texttt{SP-64} & \texttt{param2} of \texttt
{foo}\\
- \texttt{SP+8} & \texttt{SP-72} & \texttt{param1} of \texttt {foo}\\
- \texttt{SP} & -- & \texttt{IP} of callee\\
- \texttt{SP-8} & -- & Possible local variable of \texttt{foo}\\
- \bottomrule
- \end{tabular}
- \end{table}\\ \\
- As can be seen, the offsets before and after the call differ by
\texttt{72+8=80} as explained above. GoGC does not use base or frame
pointers, but relies only on the stack pointer to perform all offset
calculations. The return value is always located "after" the other
parameters and can be used as the RHS of an assignment with its known
offset as explained with the parameters above. After the function call, 80
is added to the stack pointer in order to restore the previous stack "view"
for the callee. Optionally saved registered are restored considering their
additional offset in reverse order.\\
- Internally, a function is represented by a \texttt{TypeDesc}
(compare table \ref{tbl:typedesc}) where the fields represent the functions
parmaeters, including an optional return value at their end. When a
function is being called without prior declaration, the parameter types
have to be derived from the types of the expressions encountered. As the
total number of parameters is unknown before the end function call in the
input file, a marker is inserted in the output code and comments to
indicate that the final offset has yet to be determined. As the offset due
to local variables is known, it is included. Due to the marker which
includes information about the name of the function called, the linker is
able to adapt the unfinished offsets in order to correct them accordingly.\\
- When functions have been called, but not declared, and then called
again, the type check included in the code generation for assignments is
already effective and detects improper assignment types. However, it is
necessary to extend this check as the first call can p.e. be with a
parameter of type \texttt{byte} and the second call with a parameter of
type \texttt{uint64}. This is allowed, as a \texttt{byte} type represents a
subset of the \texttt{uint64} type, requiring a conversion for the former
in order to assure that the 7 additional bytes are zero. This can be done
by simply extending the type check of the assignment. This also applies to
the return value (as it is treated like a parameter), although it has to be
considered that calls of functions without return value assignments do not
necessarily mean that the function called has no return value. Therefore,
additional checks are necessary, including the check of the return value's
existence and type when the actual function declaration is being made.
-
- \section{Global variable initialization}
- Besides the compiled functions from the input file, the code
segment contains a function called main.init which performs the
initialization of global variables. In contrast to local variables which
can be initialized directly at point of their declaration, global variables
need to be initialized before any other methods are called, thus requiring
the main.init function.\\
- Global variables in general are stored in the data segment, called
\texttt{data} in the output. They are addressed by their corresponding
symbol table offsets relative to the beginning of the data segment. For the
special treatment of string constants, please refer to the next section.
-
- \section{String constants} \label{String constants}
- Strings in Go are 16 bytes in size, containing an 8 byte address
(pointer) to its character buffer and an 8 byte length (of which only 4
bytes are used). This makes string length calculations unnecessary and also
explains why strings in Go are read-only and have to be reallocated when
being changed.\\
- Whenever a string constant is found in the input code, a new byte
array with the string's length is declared and initialized with the
string's characters. Next, another 16 bytes are allocated which represent
the actual string. Using the main.init function as described in the
previous section, the string's length and the previously allocated byte
array address are assigned to the according offsets of the string in the
data segment. When assigning the string constant (or using it as a
parameter), an item representing a data segment variable with the string's
address is used, therefore eliminating the need for any further special
treatment.
-
- \chapter{Library and run time}
- In order to be able to perform I/O operations and memory management, a
library called libgogo is implemented which wraps Linux syscalls and
provides an easy to use interface to the GoGC compiler. As GoGC generates
assembly code for 64 bit Linux operating systems and the Go compiler allows
to mix assembly and Go code, the operating system's built-in functions can
be used via syscalls in order to provide the functionality described above.
-
- \section{I/O syscalls}
- Besides read and write operations to files (and the console),
exiting the program as well as opening and closing files requires the use
of syscalls. On Linux 64 bit operating systems with Intel architecture,
these syscalls can be invoked by the assembly mnemonic \texttt{SYSCALL}
where the register \texttt{RAX} contains the syscall number defining the
syscall, and the registers \texttt{RDI}, \texttt{RSI} and \texttt{RDX}
contain the first, second and third parameter respectively\cite{var08}.\\
- The following table \ref{tbl:syscalls} lists the syscalls used by
libgogo, together with the value of \texttt{RAX} representing the syscall
number. The latter were derived from the C constants defined in
\texttt{/usr/src/linux-headers-2.6.32-22/arch/x86/include/asm/unistd\_64.h}
of the current Linux kernel source\cite{var10}. The syscall function
prototypes (for semantics and formal parameters) were derived from the
corresponding Linux man pages (see \cite{var97} and others).
-
- \begin{table}[htb]
- \centering
- \begin{tabular}{ccc}
- \toprule
- \textbf{Syscall number (\texttt{RAX})} & \textbf{Syscall function}
& \textbf{Purpose}\\
- \midrule
- 0 & \texttt{sys\_read} & Reads from a file\\
- 1 & \texttt{sys\_write} & Writes to a file\\
- 2 & \texttt{sys\_open} & Opens a file\\
- 3 & \texttt{sys\_close} & Closes a file\\
- 12 & \texttt{sys\_brk} & See next section\\
- 60 & \texttt{sys\_exit} & Exits the program\\
- \bottomrule
- \end{tabular}
- \caption{Syscalls}
- \label{tbl:syscalls}
- \end{table}
-
- \section{Memory manager}
- Libgogo provides a very simple memory manager using a bump pointer
which can allocate, but not free memory. By using the
\texttt{sys\_brk}\cite{var97} function, the memory manager expands the data
segment of the running program in steps of 10 KB if necessary in order to
deal with subsequent allocations.\\
- As the Go compiler used for boot strapping uses a custom memory
manager in its run time environment, the libgogo memory manager and the
GoGC compiler take measures to avoid conflicts with the former. First and
foremost, all implicit and explicit memory allocations in the GoGC compiler
rely on the libgogo memory manager in order to keep the amount of memory
allocated by the Go run time constant. Additionally, the memory manager
does not allocate any memory in the original data segment to not overwrite
any string constants or other information stored there by the Go run time.
This is achieved by directly expanding the data segment during the
initialization of the libgogo memory manager which also allows to store the
first address allocated, thus being able to distinguish between memory
allocated by the libgogo memory manager and memory allocated by the Go run
time.
-
- \section{String memory management}
- Based on the memory manager described above, functions to copy and
append strings are implemented in libgogo. As strings in Go are read-only
once they are created (or appended), subsequent appending operands require
the string to be entirely copied to a new memory location first. In order
to avoid this in most cases, the functions handling string appending in
libgogo allocate more memory than needed for the current operation in order
to be able to reuse this memory in subsequent append operations if the
string appended is short enough to fit in the memory already allocated.\\
- Empirical testing showed that it is most convenient to allocate the
next power of two of the string length required (p.e. 16 if 9 bytes are
initially required). This reduces the number of copy operations and thus
memory consumption by more than a power of 10 for very large strings and
small appended string (which is common appending code output).\\
- The string manager also has to take care of strings which have been
allocated by the Go run time as those strings don't have any "spare" bytes
left. Thus, a reallocation of memory for these strings is necessary and
cannot be avoided. Subsequent allocations (after the reallocation) can then
be dealt with as described above, leading to the performance gains
mentioned. The distinction between strings allocated by the Go run time and
the libgogo memory manager can be performed easily by comparing the
string's address with the first address available to the libgogo memory
manager as described in the previous section. If the string's address is
smaller, the string is not yet managed by the libgogo memory manager.
-
- \section{Program parameter determination}
- Usually, a program's parameters are accessible through \texttt{argc}
and \texttt{argv}, positioned on the stack as function parameters of the
main (entry) function. As the Go compiler used for bootstrapping adds run
time routines which are invoked before the main function, the parameters
cannot be fetched from the stack as their position cannot be determined.
The Go compiler allows to access these parameters using a separate package
(library) which could not be used in order to remain independent of third
party libraries.\\
- The current approach to fetch parameters requires the activation of
the \texttt{proc} file system in the Linux kernel which is enabled by
default in most Linux distributions\cite{var06}. The \texttt{proc} file
system allows (among other information) to access parameters of all
processes running in the system, including the current process. The
latter's parameters can be through the virtual file
\texttt{/proc/self/cmdline} where \texttt{self} refers to the current
process. The virtual file contains all parameters, separated by zero bytes
and terminated by a sequence of two zero bytes. When parsed, this allows to
access the program's parameters without having to access the stack.
-
- \chapter{Building / Self-compilation}
- \label{chpt:building}
- This section deals with the building process of GoGC and how
self-compilation
- is achieved.
-
- \section{Go language tools}
- Before introducing the compilation procedure it is important to know
how
- the Go language tools (which are actually Plan9 tools) are organized.
-
- Each CPU architecture gets a number that is prefixed before a tool.
In
- GoGC's case this would be \texttt{6}, indicating an AMD64
architecture.
- The tool suite is then organized into various compilers/linkers:
- \begin{itemize}
- \item \texttt{6a} - Assembler for AMD64 architecture (creating
\texttt{*.6}
- object files)
- \item \texttt{6g} - Go compiler for AMD64 architecture (creating
\texttt{*.6}
- object files)
- \item \texttt{6l} - Linker creating an AMD64 ELF binary out of
object files
- \end{itemize}
- Again, the file extensions of the object format indicate the CPU
- architecture used.
-
- \section{Boot-strapping}
- To create the initial compiler that is then used for subsequent
- compilations, the Go language tools are used. Go uses
\texttt{Makefile}s
- for defining the appropriate compilation procedure. Basically, three
steps
- are needed to create the GoGC binary:
- \begin{enumerate}
- \item Library compilation - The \texttt{6g} and \texttt{6a} tools
are
- used to create a single object file containing the library code.
- \item Compiler compilation - Compile the compiler using
\texttt{6g}.
- \item Link - Link the compiler object file and the library object
file
- into an ELF binary using \texttt{6l}.
- \end{enumerate}
- At the end of this procedure, an architecture-dependent (AMD64) GoGC
- compiler has been created.
-
- \section{Self-compilation}
- \label{sec:sc}
- After creating a first bootstrapped version of the compiler, this
one may
- be used for self-compilation. GoGC is written in the same language it
- is able to compile to assembly level. Therefore, no further additions
- or changes have to be made to the source code.
- The procedure to achieve self-compilation until assembly level is
shown
- in figure \ref{fig:sc}.
-
- \begin{figure}
- \centering
- \includegraphics[scale=0.4,angle=-90,clip=true,trim=0cm 0cm 3cm
0cm]{files/building}
- \label{fig:sc}
- \caption{Self-compilation approach}
- \end{figure}
-
- Although GoGC is capable of doing some very basic linking (i.e. copy
- functions from different files and adjust the symbol table), it is
not
- possible to use separate compilation during self-compilation. Altough
- function linking would work, GoGC is not able to handle global
variables
- that are spread over multiple packages correctly in the linking
process.
- Thus, the approach is straight-forward and can be summarized by the
following:
- \begin{enumerate}
- \item All sources, this includes library, as well as compiler
sources,
- are compiled in one step. The bootstrapped compiler is used in
compile
- mode for this step.
- File ordering does not matter as long as there are no forward
declared global
- variables involved (where a type has to be known). While
\texttt{*.go}
- files are compiled, \texttt{*.s} files are treated as assembly
and
- directly copied into the output.
- \item The compiled source file (\_gogo\_.sog) is then again
processed by
- the bootstrapped compiler in the linker mode. This mode is used
to fix
- offset addresses in the parameter handling of previously forward
declared functions.
- \item The received file (\_final\_.sog) then contains the compiled
- compiler in assembly language.
- \item Finally, this file is used as input for
\texttt{6a}/\texttt{6l} to
- create a platform-dependent ELF binary. This is not part of the
self-compilation,
- but necessary to get an executable file.
- \end{enumerate}
-
- In order to perform a fixpoint-test, this procedure is used to
generate
- another instance using the previously compiled GoGC compiler. The
- fixpoint-test passes and there are no differences in subsequent
compilations.
-
- \chapter{Testing}
- In order to test the compiler, a test suite (using \texttt{bash}) has
been
- constructed that may be used to verify results against an already
existing
- result set. \\ \\
- The test suite offers the following functions:
- \begin{itemize}
- \item \textbf{newvalids/ackvalids/fullclean} -- These commands are
used to
- create a new result set as reference for further tests. While
- \texttt{fullclean} deletes the old set, \texttt{newvalids} is used
to
- create a new one. After verifying that the compiled output is
correct
- (by manually checking it), the command \texttt{ackvalids} can be
used to
- acknowledge the set (resulting in a checksum file).
- \item \textbf{test/clean} -- \texttt{test} is used to perform a
- compilation and compare the results against the last valid result
set.
- In order to do so, checksums of the tests are compared. If they
are not
- equal, a \texttt{diff} is printed to the user. \texttt{Clean}
deletes
- all temporary files.
- \end{itemize}
- Listing \ref{lst:test} shows the usage and an example output of the
testsuite.
-\lstset{
-language=bash
-}
- \begin{lstlisting}[caption=Testsuite example,label=lst:test]
-$ ./testsuite test
-
->>> Performing internal checks
-
-Checking for sha256sum tool... ok
-Checking for gogo compiler... ok
-Checking for tests... ok
-
->>> Checking whether an acknowledged resultset exists
-
->>> Generating tests
-Checking for tmp... creating it
-
->>> Performing quick check
-* Checksums matched. Everything seems fine
- \end{lstlisting}
- \bibliographystyle{alpha}
- \bibliography{gogo}
-
-\end{document}
==============================================================================
Revision: 9544ab0b9d
Author: Scott Lawrence <
byt...@gmail.com>
Date: Fri Aug 20 11:56:45 2010
Log: on the way to a gomake-based build process
http://code.google.com/p/gogc/source/detail?r=9544ab0b9d
Modified:
/src/asm_out.go
/src/codegen.go
/src/gen-arith.go
/src/gen-assign.go
/src/gen-cond.go
/src/gen-const.go
/src/gen-expr.go
/src/gen-fcn.go
/src/gen-for.go
/src/gen-if.go
/src/globals.go
/src/gogo.go
/src/inspector.go
/src/linker.go
/src/parser.go
/src/scanner.go
/src/symtable.go
/src/token.go
/src/utils.go
=======================================
--- /src/asm_out.go Wed Aug 18 10:20:16 2010
+++ /src/asm_out.go Fri Aug 20 11:56:45 2010
@@ -4,7 +4,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
//
// Variables holding the compiled code and data segment (as assembly code)
=======================================
--- /src/codegen.go Wed Aug 18 10:20:16 2010
+++ /src/codegen.go Fri Aug 20 11:56:45 2010
@@ -9,7 +9,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
// Currently register from R8-R15 are available for usage
var NumRegisters uint64 = 8
=======================================
--- /src/gen-arith.go Wed Aug 18 10:20:16 2010
+++ /src/gen-arith.go Fri Aug 20 11:56:45 2010
@@ -9,7 +9,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
//
// item1 = item1 OP item2, or constvalue if both item1 and item2 are
constants
=======================================
--- /src/gen-assign.go Wed Aug 18 10:20:16 2010
+++ /src/gen-assign.go Fri Aug 20 11:56:45 2010
@@ -8,7 +8,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
func GenerateAssignment(LHSItem *libgogo.Item, RHSItem *libgogo.Item,
address uint64) {
if Compile != 0 {
=======================================
--- /src/gen-cond.go Wed Aug 18 10:20:16 2010
+++ /src/gen-cond.go Fri Aug 20 11:56:45 2010
@@ -9,7 +9,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
//
// Function used to print jumps.
=======================================
--- /src/gen-const.go Wed Aug 18 10:20:16 2010
+++ /src/gen-const.go Fri Aug 20 11:56:45 2010
@@ -4,7 +4,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
func CreateIntegerConstant(value uint64, item *libgogo.Item) {
if value <= 255 { //Value fits into byte_t
=======================================
--- /src/gen-expr.go Wed Aug 18 10:20:16 2010
+++ /src/gen-expr.go Fri Aug 20 11:56:45 2010
@@ -8,7 +8,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
func SwapExpressionBranches(ed *ExpressionDescriptor) {
var stacksize uint64
=======================================
--- /src/gen-fcn.go Wed Aug 18 10:20:16 2010
+++ /src/gen-fcn.go Fri Aug 20 11:56:45 2010
@@ -4,7 +4,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
func ZeroParameterCheck(FunctionCalled *libgogo.TypeDesc) {
var FullFunctionName string = ""
=======================================
--- /src/gen-for.go Wed Aug 18 10:20:16 2010
+++ /src/gen-for.go Fri Aug 20 11:56:45 2010
@@ -8,7 +8,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
func GenerateForStart(item *libgogo.Item, ed *ExpressionDescriptor) {
var labelString string
=======================================
--- /src/gen-if.go Wed Aug 18 10:20:16 2010
+++ /src/gen-if.go Fri Aug 20 11:56:45 2010
@@ -8,7 +8,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
func GenerateIfStart(item *libgogo.Item, ed *ExpressionDescriptor) {
var labelString string
=======================================
--- /src/globals.go Wed Aug 18 10:20:16 2010
+++ /src/globals.go Fri Aug 20 11:56:45 2010
@@ -8,7 +8,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
//
// Struct holding the information about a file that is compiled
=======================================
--- /src/gogo.go Wed Aug 18 10:20:16 2010
+++ /src/gogo.go Fri Aug 20 11:56:45 2010
@@ -4,7 +4,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
//
// Entry point of the compiler
=======================================
--- /src/inspector.go Wed Aug 18 10:20:16 2010
+++ /src/inspector.go Fri Aug 20 11:56:45 2010
@@ -4,7 +4,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
func InspectorGadget() {
libgogo.StringAppend(&Header, `
=======================================
--- /src/linker.go Wed Aug 18 10:20:16 2010
+++ /src/linker.go Fri Aug 20 11:56:45 2010
@@ -4,7 +4,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
type LineDesc struct {
Line string
=======================================
--- /src/parser.go Wed Aug 18 10:20:16 2010
+++ /src/parser.go Fri Aug 20 11:56:45 2010
@@ -4,7 +4,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
var Operators libgogo.Stack
=======================================
--- /src/scanner.go Wed Aug 18 10:20:16 2010
+++ /src/scanner.go Fri Aug 20 11:56:45 2010
@@ -7,7 +7,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
//
// Function fetching a new character from the file that is compiled
=======================================
--- /src/symtable.go Wed Aug 18 10:20:16 2010
+++ /src/symtable.go Fri Aug 20 11:56:45 2010
@@ -4,7 +4,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
//
// List of global objects and declared types
=======================================
--- /src/token.go Wed Aug 18 10:20:16 2010
+++ /src/token.go Fri Aug 20 11:56:45 2010
@@ -4,7 +4,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
//
// Token struct holding the relevant token data.
=======================================
--- /src/utils.go Wed Aug 18 10:20:16 2010
+++ /src/utils.go Fri Aug 20 11:56:45 2010
@@ -4,7 +4,7 @@
package main
-import "./libgogo/_obj/libgogo"
+import "./libgogo"
var maxErrors uint64 = 10
var errors uint64 = 0
==============================================================================
Revision: b0d4dfb141
Author: Scott Lawrence <
byt...@gmail.com>
Date: Fri Aug 20 12:05:04 2010
Log: partial top-level Makefiles
http://code.google.com/p/gogc/source/detail?r=b0d4dfb141
Added:
/Makefile
/Makefile.deps
/Makefile.info
=======================================
--- /dev/null
+++ /Makefile Fri Aug 20 12:05:04 2010
@@ -0,0 +1,23 @@
+# Copyright 2010 The GoGC Authors. All rights reserved.
+# Use of this source code is governed by the MIT
+# license that can be found in the LICENSE file.
+
+.PHONY: all clean install format
+
+all: gogc
+
+include ${GOROOT}/src/Make.${GOARCH}
+include Makefile.info
+
+gogc: src/gogo
+
+install:
+ @echo not yet implemented
+
+format:
+ gofmt -w ${GOFILES}
+
+clean:
+ rm -f gogc
+
+include Makefile.deps
=======================================
--- /dev/null
+++ /Makefile.deps Fri Aug 20 12:05:04 2010
@@ -0,0 +1,8 @@
+# external packages: os ../_obj/libgogo fmt
+libgogo.${O}: src/libgogo/convert.go src/libgogo/io.go src/libgogo/item.go
src/libgogo/libgogo.go src/libgogo/list.go src/libgogo/memmgr.go
src/libgogo/stack.go src/libgogo/string.go src/libgogo/strlist.go
src/libgogo/symbol.go
+src/fib: src/fib.${O}
+src/gogo: src/gogo.${O}
+src/libgogo/test/libgogotest: src/libgogo/test/libgogotest.${O}
+src/fib.${O}: src/fib.go src/asm_out.go src/codegen.go src/gen-arith.go
src/gen-assign.go src/gen-cond.go src/gen-const.go src/gen-expr.go
src/gen-fcn.go src/gen-for.go src/gen-if.go src/globals.go src/inspector.go
src/linker.go src/parse-utils.go src/parser.go src/scanner.go
src/symtable.go src/token.go src/utils.go libgogo.${O}
+src/gogo.${O}: src/gogo.go src/asm_out.go src/codegen.go src/gen-arith.go
src/gen-assign.go src/gen-cond.go src/gen-const.go src/gen-expr.go
src/gen-fcn.go src/gen-for.go src/gen-if.go src/globals.go src/inspector.go
src/linker.go src/parse-utils.go src/parser.go src/scanner.go
src/symtable.go src/token.go src/utils.go libgogo.${O}
+src/libgogo/test/libgogotest.${O}: src/libgogo/test/libgogotest.go
src/asm_out.go src/codegen.go src/gen-arith.go src/gen-assign.go
src/gen-cond.go src/gen-const.go src/gen-expr.go src/gen-fcn.go
src/gen-for.go src/gen-if.go src/globals.go src/inspector.go src/linker.go
src/parse-utils.go src/parser.go src/scanner.go src/symtable.go
src/token.go src/utils.go libgogo.${O}
=======================================
--- /dev/null
+++ /Makefile.info Fri Aug 20 12:05:04 2010
@@ -0,0 +1,1 @@
+GOFILES = src/asm_out.go src/codegen.go src/fib.go src/gen-arith.go
src/gen-assign.go src/gen-cond.go src/gen-const.go src/gen-expr.go
src/gen-fcn.go src/gen-for.go src/gen-if.go src/globals.go src/gogo.go
src/inspector.go src/libgogo/convert.go src/libgogo/io.go
src/libgogo/item.go src/libgogo/libgogo.go src/libgogo/list.go
src/libgogo/memmgr.go src/libgogo/stack.go src/libgogo/string.go
src/libgogo/strlist.go src/libgogo/symbol.go
src/libgogo/test/libgogotest.go src/linker.go src/parse-utils.go
src/parser.go src/scanner.go src/symtable.go src/token.go src/utils.go
==============================================================================
Revision: 10477faa93
Author: Scott Lawrence <
byt...@gmail.com>
Date: Fri Aug 20 14:01:45 2010
Log: added header comment to AUTHORS
http://code.google.com/p/gogc/source/detail?r=10477faa93
Modified:
/AUTHORS
=======================================
--- /AUTHORS Sun Aug 15 15:43:36 2010
+++ /AUTHORS Fri Aug 20 14:01:45 2010
@@ -1,3 +1,6 @@
+# List of authors of GOGC
+# Please keep this alphabetical
+
Scott Lawrence <
byt...@gmail.com>
Michael Lippautz <
michael....@sbg.ac.at>
Andreas Unterweger <
andreas.u...@sbg.ac.at>