summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-05-31 15:02:46 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2020-05-31 15:02:46 +0200
commit391b6e0958be1f6d00c5f3c7e57fee87bec965ef (patch)
tree9400faddb3f157657c0e8b5d23a00abf9ebe0c63
parent0307ad956911c1fbb526e002e2611f2037d986f2 (diff)
downloadcompilertests-391b6e0958be1f6d00c5f3c7e57fee87bec965ef.tar.gz
compilertests-391b6e0958be1f6d00c5f3c7e57fee87bec965ef.tar.bz2
added support for multi-operand db in asm-i386 for string definitions
added string and character tests
-rw-r--r--ecomp-c/asm-i386.c45
-rw-r--r--ecomp-c/ec.c44
-rw-r--r--ecomp-c/minie.ebnf4
-rwxr-xr-xecomp-c/test.sh2
-rw-r--r--ecomp-c/tests/asm-i386/mov.asm1
-rw-r--r--ecomp-c/tests/character_variable.e15
-rw-r--r--ecomp-c/tests/character_variable.easm14
-rw-r--r--ecomp-c/tests/character_variable.easm_err0
-rw-r--r--ecomp-c/tests/character_variable.ecomp_err0
-rw-r--r--ecomp-c/tests/character_variable.erun158
-rw-r--r--ecomp-c/tests/string_variable.e16
-rw-r--r--ecomp-c/tests/string_variable.easm11
-rw-r--r--ecomp-c/tests/string_variable.easm_err0
-rw-r--r--ecomp-c/tests/string_variable.ecomp_err0
-rw-r--r--ecomp-c/tests/string_variable.erun48
15 files changed, 325 insertions, 33 deletions
diff --git a/ecomp-c/asm-i386.c b/ecomp-c/asm-i386.c
index fd4ab1a..ba62fc8 100644
--- a/ecomp-c/asm-i386.c
+++ b/ecomp-c/asm-i386.c
@@ -48,7 +48,7 @@
* use32
* org 0x0000
* dd 0x0000
- * db 0x00
+ * db 0x00 (1 to N arguments), combinable with string literals
* db "abcd"
*/
@@ -214,8 +214,14 @@ static int isHexDigit( int c )
static int isSpecial( int c )
{
- if( c == '_' ) return 1;
- return 0;
+ switch( c ) {
+ case '_':
+ case ' ':
+ return 1;
+
+ default:
+ return 0;
+ }
}
static void skipWhite( void )
@@ -302,11 +308,11 @@ static void identifier( void )
{
int n = 0;
- if( isAlpha( look ) || isSpecial( look ) ) {
+ if( isAlpha( look ) || ( look == '_' ) ) {
ident[n] = look;
n++;
look = getChar( );
- while( ( isAlpha( look ) || isDigit( look ) || isSpecial( look ) ) && n < MAX_IDENT_LEN ) {
+ while( ( isAlpha( look ) || isDigit( look ) || ( look == '_' ) ) && n < MAX_IDENT_LEN ) {
ident[n] = look;
n++;
look = getChar( );
@@ -934,7 +940,7 @@ static void assign_label( OperandInfo *operand_info, char *label )
}
}
-static OperandInfo *parseOperand( void )
+static OperandInfo *parseOperand( OpcodeInfo *opcode_info )
{
OperandInfo *operand_info;
@@ -962,6 +968,7 @@ static OperandInfo *parseOperand( void )
} else if( sym == S_string ) {
operand_info->type = OPERAND_ABSOLUTE;
operand_info->str = AllocateAndCopyStr( str );
+ opcode_info->size = strlen( str );
sym = getSym( );
} else if( sym == S_lbrak ) {
/* pointer indirection as [a] */
@@ -996,18 +1003,18 @@ static void parseOperands( OpcodeInfo *opcode_info )
OperandInfo *operand_info;
while( sym != S_newline ) {
- operand_info = parseOperand( );
+ operand_info = parseOperand( opcode_info );
append_operand( opcode_info, operand_info );
nof_operands++;
while( sym == S_comma ) {
sym = getSym( );
- operand_info = parseOperand( );
+ operand_info = parseOperand( opcode_info );
append_operand( opcode_info, operand_info );
nof_operands++;
}
}
- if( nof_operands != opcode_info->nof_operands ) {
+ if( opcode_info->opcode != OPCODE_PSEUDO_DB && nof_operands != opcode_info->nof_operands ) {
Abort( "'%s' expects %d operand(s), %d given", opcodename[opcode_info->opcode], opcode_info->nof_operands, nof_operands );
}
@@ -1450,6 +1457,8 @@ static void generate_code( OpcodeInfo *opcode_info )
static void emit_opcode( OpcodeInfo *opcode_info )
{
+ OperandInfo *operand;
+
switch( opcode_info->opcode ) {
case OPCODE_PSEUDO_ORG:
break;
@@ -1457,14 +1466,18 @@ static void emit_opcode( OpcodeInfo *opcode_info )
Emit_double_little_endian( opcode_info->operand->num );
break;
case OPCODE_PSEUDO_DB:
- if( opcode_info->operand->str == NULL ) {
- Emit_byte( opcode_info->operand->num );
- } else {
- int i;
- int len = strlen( opcode_info->operand->str );
- for( i = 0; i < len; i++ ) {
- Emit( "%c", opcode_info->operand->str[i] );
+ operand = opcode_info->operand;
+ while( operand != NULL ) {
+ if( operand->str == NULL ) {
+ Emit_byte( operand->num );
+ } else {
+ int i;
+ int len = strlen( operand->str );
+ for( i = 0; i < len; i++ ) {
+ Emit( "%c", operand->str[i] );
+ }
}
+ operand = operand->next;
}
break;
case OPCODE_HLT:
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c
index 80bc815..87a3012 100644
--- a/ecomp-c/ec.c
+++ b/ecomp-c/ec.c
@@ -203,8 +203,14 @@ static int isDigit( int c )
static int isSpecial( int c )
{
- if( c == '_' ) return 1;
- return 0;
+ switch( c ) {
+ case '_':
+ case ' ':
+ return 1;
+
+ default:
+ return 0;
+ }
}
static void skipWhite( void )
@@ -1733,6 +1739,9 @@ static void prologue( void )
static void reserve_initialize( Symbol *symbol )
{
+ int i;
+ int len;
+
switch( symbol->type->class ) {
case SYMBOL_CLASS_SIMPLE_TYPE:
if( symbol->type == integer_type ) {
@@ -1751,28 +1760,33 @@ static void reserve_initialize( Symbol *symbol )
Emit( "\n" );
break;
- case SYMBOL_CLASS_ARRAY_TYPE: {
- int i = 0;
-
+ case SYMBOL_CLASS_ARRAY_TYPE:
if( symbol->type->type == character_type ) {
- int len = strlen( symbol->string_value );
- Emit( "db \"" );
- while( i < len ) {
- Emit( "%c", symbol->string_value[i] );
- i++;
+ i = 0;
+ Emit( "db " );
+ if( symbol->string_value != NULL ) {
+ Emit( "\"" );
+ len = strlen( symbol->string_value );
+ while( i < len ) {
+ Emit( "%c", symbol->string_value[i] );
+ i++;
+ }
+ Emit( "\"" );
}
- Emit( "\"" );
while( i < symbol->type->dim ) {
- Emit( "$00" );
+ if( i > 0 ) {
+ Emit( ", " );
+ }
+ Emit( "0" );
+ i++;
}
Emit( "\n" );
} else {
for( i = 0; i < symbol->type->dim; i++ ) {
reserve_initialize( symbol->type );
}
- }
-
- } break;
+ }
+ break;
default:
Abort( "Unhandled variable space reservation and initializiation for complex type '%s' in variable '%s'",
diff --git a/ecomp-c/minie.ebnf b/ecomp-c/minie.ebnf
index 6404899..c4d9513 100644
--- a/ecomp-c/minie.ebnf
+++ b/ecomp-c/minie.ebnf
@@ -1,10 +1,10 @@
Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" .
Letter = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" |
"a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" .
-Special = "_" .
+Special = "_" | " " .
Identifier = Letter { Letter | Digit | "_" } .
Number = Digit { Digit } .
-Character = "'" Digit | Letter | Special "'" .
+Character = "'" Digit | Letter | Special | "'" .
String = """" { Character } """" .
Factor = Number | Character | String | Identifier | "(" Expression ")" | "not" Factor .
diff --git a/ecomp-c/test.sh b/ecomp-c/test.sh
index 94bed3b..a17d78e 100755
--- a/ecomp-c/test.sh
+++ b/ecomp-c/test.sh
@@ -16,6 +16,8 @@ variable_assign_from_type
variable_assign_from_variable
variable_assign_from_expression
boolean_variable
+character_variable
+string_variable
if_statement
bool_conditions
type_check_assignment
diff --git a/ecomp-c/tests/asm-i386/mov.asm b/ecomp-c/tests/asm-i386/mov.asm
index 7495e63..b823bf6 100644
--- a/ecomp-c/tests/asm-i386/mov.asm
+++ b/ecomp-c/tests/asm-i386/mov.asm
@@ -11,3 +11,4 @@ db "Hello"
flag2: db $2
db "World"
dd $01020304
+db "abc", 0, "def", 0
diff --git a/ecomp-c/tests/character_variable.e b/ecomp-c/tests/character_variable.e
new file mode 100644
index 0000000..5dbd2d1
--- /dev/null
+++ b/ecomp-c/tests/character_variable.e
@@ -0,0 +1,15 @@
+/*
+ * define a character variable
+ */
+
+module character_variable;
+
+const
+ C : character = 'A';
+var
+ c1 : character := C;
+ c2 : character := 'B';
+
+begin
+ c2 := 'C';
+end
diff --git a/ecomp-c/tests/character_variable.easm b/ecomp-c/tests/character_variable.easm
new file mode 100644
index 0000000..ec0a50a
--- /dev/null
+++ b/ecomp-c/tests/character_variable.easm
@@ -0,0 +1,14 @@
+format binary
+use32
+org $1000000
+; CONST C -> character, 'A'
+; DECL c1 -> character, 'A'
+; DECL c2 -> character, 'B'
+; LET c2 <- 'C'
+mov eax, 67
+push eax
+pop eax
+mov [c2], al
+hlt
+c2: db $42
+c1: db $41
diff --git a/ecomp-c/tests/character_variable.easm_err b/ecomp-c/tests/character_variable.easm_err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ecomp-c/tests/character_variable.easm_err
diff --git a/ecomp-c/tests/character_variable.ecomp_err b/ecomp-c/tests/character_variable.ecomp_err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ecomp-c/tests/character_variable.ecomp_err
diff --git a/ecomp-c/tests/character_variable.erun b/ecomp-c/tests/character_variable.erun
new file mode 100644
index 0000000..9c74e3b
--- /dev/null
+++ b/ecomp-c/tests/character_variable.erun
@@ -0,0 +1,158 @@
+Read 15 bytes of code..
+1000000: B843000000 mov eax, 0x43
+1000005: 50 push eax
+1000006: 58 pop eax
+1000007: A20D000001 mov byte ptr [0x100000d], al
+100000C: F4 hlt
+100000D: 42 data
+100000E: 41 data
+core start 1000000
+data start 100000d
+stack start 1800000
+Single step execution:
+-- iteration 1
+1000000: B843000000 mov eax, 0x43
+EIP: 01000005
+ESP: 01800000
+EBP: 00000000
+EAX: 00000043
+EBX: 00000000
+ECX: 00000000
+EDX: 00000000
+ESI: 00000000
+EDI: 00000000
+stack:
+data:
+0100000D: 42410000
+01000011: 00000000
+01000015: 00000000
+01000019: 00000000
+0100001D: 00000000
+01000021: 00000000
+01000025: 00000000
+01000029: 00000000
+0100002D: 00000000
+01000031: 00000000
+01000035: 00000000
+01000039: 00000000
+0100003D: 00000000
+01000041: 00000000
+01000045: 00000000
+01000049: 00000000
+-- iteration 2
+1000005: 50 push eax
+EIP: 01000006
+ESP: 017FFFFC
+EBP: 00000000
+EAX: 00000043
+EBX: 00000000
+ECX: 00000000
+EDX: 00000000
+ESI: 00000000
+EDI: 00000000
+stack:
+017FFFFC: 00000043
+data:
+0100000D: 42410000
+01000011: 00000000
+01000015: 00000000
+01000019: 00000000
+0100001D: 00000000
+01000021: 00000000
+01000025: 00000000
+01000029: 00000000
+0100002D: 00000000
+01000031: 00000000
+01000035: 00000000
+01000039: 00000000
+0100003D: 00000000
+01000041: 00000000
+01000045: 00000000
+01000049: 00000000
+-- iteration 3
+1000006: 58 pop eax
+EIP: 01000007
+ESP: 01800000
+EBP: 00000000
+EAX: 00000043
+EBX: 00000000
+ECX: 00000000
+EDX: 00000000
+ESI: 00000000
+EDI: 00000000
+stack:
+data:
+0100000D: 42410000
+01000011: 00000000
+01000015: 00000000
+01000019: 00000000
+0100001D: 00000000
+01000021: 00000000
+01000025: 00000000
+01000029: 00000000
+0100002D: 00000000
+01000031: 00000000
+01000035: 00000000
+01000039: 00000000
+0100003D: 00000000
+01000041: 00000000
+01000045: 00000000
+01000049: 00000000
+-- iteration 4
+1000007: A20D000001 mov byte ptr [0x100000d], al
+EIP: 0100000C
+ESP: 01800000
+EBP: 00000000
+EAX: 00000043
+EBX: 00000000
+ECX: 00000000
+EDX: 00000000
+ESI: 00000000
+EDI: 00000000
+stack:
+data:
+0100000D: 43410000
+01000011: 00000000
+01000015: 00000000
+01000019: 00000000
+0100001D: 00000000
+01000021: 00000000
+01000025: 00000000
+01000029: 00000000
+0100002D: 00000000
+01000031: 00000000
+01000035: 00000000
+01000039: 00000000
+0100003D: 00000000
+01000041: 00000000
+01000045: 00000000
+01000049: 00000000
+-- iteration 5
+100000C: F4 hlt
+EIP: 0100000D
+ESP: 01800000
+EBP: 00000000
+EAX: 00000043
+EBX: 00000000
+ECX: 00000000
+EDX: 00000000
+ESI: 00000000
+EDI: 00000000
+stack:
+data:
+0100000D: 43410000
+01000011: 00000000
+01000015: 00000000
+01000019: 00000000
+0100001D: 00000000
+01000021: 00000000
+01000025: 00000000
+01000029: 00000000
+0100002D: 00000000
+01000031: 00000000
+01000035: 00000000
+01000039: 00000000
+0100003D: 00000000
+01000041: 00000000
+01000045: 00000000
+01000049: 00000000
diff --git a/ecomp-c/tests/string_variable.e b/ecomp-c/tests/string_variable.e
new file mode 100644
index 0000000..e6cf1c4
--- /dev/null
+++ b/ecomp-c/tests/string_variable.e
@@ -0,0 +1,16 @@
+/*
+ * define a string variable
+ */
+
+module string_variable;
+
+const
+ S : array 11 of character = "hello world";
+
+var
+ s1 : array 11 of character := S;
+ s2 : array 17 of character := "hello again world";
+ s3 : array 12 of character;
+
+begin
+end
diff --git a/ecomp-c/tests/string_variable.easm b/ecomp-c/tests/string_variable.easm
new file mode 100644
index 0000000..48b3639
--- /dev/null
+++ b/ecomp-c/tests/string_variable.easm
@@ -0,0 +1,11 @@
+format binary
+use32
+org $1000000
+; CONST S -> array 11 of character, array 11 of character = { ... }
+; DECL s1 -> array 11 of character, array 11 of character = { ... }
+; DECL s2 -> array 17 of character, array 17 of character = { ... }
+; DECL s3 -> array 12 of character, array 12 of character = { ... }
+hlt
+s3: db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+s2: db "hello again world"
+s1: db "hello world"
diff --git a/ecomp-c/tests/string_variable.easm_err b/ecomp-c/tests/string_variable.easm_err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ecomp-c/tests/string_variable.easm_err
diff --git a/ecomp-c/tests/string_variable.ecomp_err b/ecomp-c/tests/string_variable.ecomp_err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ecomp-c/tests/string_variable.ecomp_err
diff --git a/ecomp-c/tests/string_variable.erun b/ecomp-c/tests/string_variable.erun
new file mode 100644
index 0000000..1cfc309
--- /dev/null
+++ b/ecomp-c/tests/string_variable.erun
@@ -0,0 +1,48 @@
+Read 41 bytes of code..
+1000000: F4 hlt
+1000001: 0000 data
+1000003: 0000 data
+1000005: 0000 data
+1000007: 0000 data
+1000009: 0000 data
+100000B: 0000 data
+100000D: 68656C6C6F data
+1000012: 206167 data
+1000015: 61 data
+1000016: 696E20776F726C data
+100001D: 6468656C6C6F data
+1000023: 20776F data
+1000026: 726C data
+core start 1000000
+data start 1000001
+stack start 1800000
+Single step execution:
+-- iteration 1
+1000000: F4 hlt
+EIP: 01000001
+ESP: 01800000
+EBP: 00000000
+EAX: 00000000
+EBX: 00000000
+ECX: 00000000
+EDX: 00000000
+ESI: 00000000
+EDI: 00000000
+stack:
+data:
+01000001: 00000000
+01000005: 00000000
+01000009: 00000000
+0100000D: 68656C6C
+01000011: 6F206167
+01000015: 61696E20
+01000019: 776F726C
+0100001D: 6468656C
+01000021: 6C6F2077
+01000025: 6F726C64
+01000029: 00000000
+0100002D: 00000000
+01000031: 00000000
+01000035: 00000000
+01000039: 00000000
+0100003D: 00000000