diff --git a/check.t b/check.t
index 4d87fa1..6459eff 100644
--- a/check.t
+++ b/check.t
@@ -1,4 +1,4 @@
-# $MirOS: src/bin/mksh/check.t,v 1.115 2007/06/21 16:04:45 tg Exp $
+# $MirOS: src/bin/mksh/check.t,v 1.116 2007/06/22 23:34:40 tg Exp $
 # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
 # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
 # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@@ -7,7 +7,7 @@
 # http://www.research.att.com/~gsf/public/ifs.sh
 
 expected-stdout:
-	@(#)MIRBSD KSH R29 2007/06/21
+	@(#)MIRBSD KSH R29 2007/06/22
 description:
 	Check version of shell.
 category: pdksh
@@ -4009,3 +4009,23 @@ expected-stdout:
 	integer='typeset -i'
 	local=typeset
 ---
+name: arrays-1
+description:
+	Check if Korn Shell arrays work as expected
+stdin:
+	v="c d"
+	set -A foo -- a \$v "$v" '$v' b
+	echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|"
+expected-stdout:
+	5|a|$v|c d|$v|b|
+---
+name: arrays-2
+description:
+	Check if bash-style arrays work as expected
+stdin:
+	v="c d"
+	foo=(a \$v "$v" '$v' b)
+	echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|"
+expected-stdout:
+	5|a|$v|c d|$v|b|
+---
diff --git a/lex.c b/lex.c
index b8926a9..2fcbc29 100644
--- a/lex.c
+++ b/lex.c
@@ -2,7 +2,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.35 2007/06/16 15:02:56 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.36 2007/06/22 23:34:40 tg Exp $");
 
 /* Structure to keep track of the lexing state and the various pieces of info
  * needed for each particular state. */
@@ -37,6 +37,12 @@ struct lex_state {
 		} u_sbquote;
 
 		Lex_state *base;	/* used to point to next state block */
+
+		/* =(...) */
+		struct sletarray_info {
+			int nparen;	/* count open parentheses */
+#define ls_sletarray ls_info.u_sletarray
+		} u_sletarray;
 	} ls_info;
 };
 
@@ -121,6 +127,9 @@ yylex(int cf)
 		*wp++ = OQUOTE;	 /* enclose arguments in (double) quotes */
 		state = SLETPAREN;
 		statep->ls_sletparen.nparen = 0;
+	} else if (cf&LETARRAY) {
+		state = SLETARRAY;
+		statep->ls_sletarray.nparen = 0;
 	} else {		/* normal lexing */
 		state = (cf & HEREDELIM) ? SHEREDELIM : SBASE;
 		while ((c = getsc()) == ' ' || c == '\t')
@@ -535,6 +544,17 @@ yylex(int cf)
 				++statep->ls_sletparen.nparen;
 			goto Sbase2;
 
+		case SLETARRAY:	/* LETARRAY: =( ... ) */
+			if (c == '('/*)*/)
+				++statep->ls_sletarray.nparen;
+			else if (c == /*(*/')')
+				if (statep->ls_sletarray.nparen-- == 0) {
+					c = 0;
+					goto Done;
+				}
+			*wp++ = CHAR, *wp++ = c;
+			break;
+
 		case SHEREDELIM:	/* <<,<<- delimiter */
 			/* XXX chuck this state (and the next) - use
 			 * the existing states ($ and \`..` should be
@@ -607,6 +627,9 @@ yylex(int cf)
 		/* XXX figure out what is missing */
 		yyerror("no closing quote\n");
 
+	if (state == SLETARRAY && statep->ls_sletarray.nparen != -1)
+		yyerror("syntax error: ')' missing\n");
+
 	/* This done to avoid tests for SHEREDELIM wherever SBASE tested */
 	if (state == SHEREDELIM)
 		state = SBASE;
@@ -680,7 +703,8 @@ yylex(int cf)
 
 	*wp++ = EOS;		/* terminate word */
 	yylval.cp = Xclose(ws, wp);
-	if (state == SWORD || state == SLETPAREN)	/* ONEWORD? */
+	if (state == SWORD || state == SLETPAREN ||
+	    state == SLETARRAY)	/* ONEWORD? */
 		return LWORD;
 	ungetsc(c);		/* unget terminator */
 
diff --git a/mksh.1 b/mksh.1
index 1a0178e..450befa 100644
--- a/mksh.1
+++ b/mksh.1
@@ -1,7 +1,7 @@
-.\" $MirOS: src/bin/mksh/mksh.1,v 1.87 2007/06/17 00:50:08 tg Exp $
+.\" $MirOS: src/bin/mksh/mksh.1,v 1.88 2007/06/22 23:34:41 tg Exp $
 .\" $OpenBSD: ksh.1,v 1.120 2007/05/31 20:47:44 otto Exp $
 .\"
-.Dd June 17, 2007
+.Dd June 22, 2007
 .Dt MKSH 1
 .Os MirBSD
 .Sh NAME
@@ -3208,6 +3208,17 @@ is used, the array is reset (i.e. emptied) first; if
 .Ic +A
 is used, the first N elements are set (where N is the number of arguments);
 the rest are left untouched.
+.Pp
+An alternative syntax for the command
+.Ic set -A foo -- a b c
+which is compatible to
+.Tn GNU
+.Nm bash
+and also supported by
+.At
+.Nm ksh93
+is:
+.Ic foo=(a b c)
 .It Fl a \*(Ba Ic allexport
 All new parameters are created with the export attribute.
 .It Fl b \*(Ba Ic notify
diff --git a/sh.h b/sh.h
index 3d55d2e..dba80df 100644
--- a/sh.h
+++ b/sh.h
@@ -8,8 +8,8 @@
 /*	$OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $	*/
 /*	$OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $	*/
 
-#define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.149 2007/06/21 16:04:46 tg Exp $"
-#define MKSH_VERSION "R29 2007/06/21"
+#define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.150 2007/06/22 23:34:41 tg Exp $"
+#define MKSH_VERSION "R29 2007/06/22"
 
 #if HAVE_SYS_PARAM_H
 #include <sys/param.h>
@@ -1112,6 +1112,7 @@ struct source {
 #define SHEREDQUOTE	10	/* parsing " in <<,<<- delimiter */
 #define SPATTERN	11	/* parsing *(...|...) pattern (*+?@!) */
 #define STBRACE		12	/* parsing ${..[#%]..} */
+#define SLETARRAY	13	/* inside =( ), just copy */
 
 typedef union {
 	int i;
@@ -1162,6 +1163,7 @@ typedef union {
 #define HEREDELIM	BIT(9)	/* parsing <<,<<- delimiter */
 #define LQCHAR		BIT(10)	/* source string contains QCHAR */
 #define HEREDOC		BIT(11)	/* parsing a here document */
+#define LETARRAY	BIT(12)	/* copy expression inside =( ) */
 
 #define HERES	10		/* max << in line */
 
diff --git a/syn.c b/syn.c
index ad4e369..77cebd1 100644
--- a/syn.c
+++ b/syn.c
@@ -2,7 +2,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.14 2007/06/06 23:28:17 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.15 2007/06/22 23:34:42 tg Exp $");
 
 struct nesting_state {
 	int start_token;	/* token than began nesting (eg, FOR) */
@@ -248,6 +248,9 @@ get_command(int cf)
 					ACCEPT;
 					goto Subshell;
 				}
+				if ((XPsize(args) == 0 || Flag(FKEYWORD)) &&
+				    XPsize(vars) == 1 && is_wdvarassign(yylval.cp))
+					goto is_wdarrassign;
 				/* Must be a function */
 				if (iopn != 0 || XPsize(args) != 1 ||
 				    XPsize(vars) != 0)
@@ -257,6 +260,41 @@ get_command(int cf)
 				musthave(')', 0);
 				t = function_body(XPptrv(args)[0], false);
 				goto Leave;
+ is_wdarrassign:
+			  {
+				static const char set_cmd0[] = {
+					CHAR, 'e', CHAR, 'v',
+					CHAR, 'a', CHAR, 'l', EOS
+				};
+				static const char set_cmd1[] = {
+					CHAR, 's', CHAR, 'e',
+					CHAR, 't', CHAR, ' ',
+					CHAR, '-', CHAR, 'A', EOS
+				};
+				static const char set_cmd2[] = {
+					CHAR, '-', CHAR, '-', EOS
+				};
+				char *tcp;
+				XPfree(vars);
+				XPinit(vars, 16);
+				/*
+				 * we know (or rather hope) that yylval.cp
+				 * contains a string "varname="
+				 */
+				tcp = wdcopy(yylval.cp, ATEMP);
+				tcp[wdscan(tcp, EOS) - tcp - 3] = EOS;
+				/* now make an array assignment command */
+				t = newtp(TCOM);
+				t->lineno = source->line;
+				ACCEPT;
+				XPput(args, wdcopy(set_cmd0, ATEMP));
+				XPput(args, wdcopy(set_cmd1, ATEMP));
+				XPput(args, tcp);
+				XPput(args, wdcopy(set_cmd2, ATEMP));
+				musthave(LWORD,LETARRAY);
+				XPput(args, yylval.cp);
+				break;
+			  }
 
 			default:
 				goto Leave;