changeset 1883:3c30ae764004 default tip

add function.canTake()
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 08 Apr 2025 13:40:37 -0600
parents f8ca4a147ac9
children
files src/luan/LuanFunction.java src/luan/LuanJavaFunction.java src/luan/impl/LuanParser.java src/luan/modules/swing/Document.luan src/luan/modules/swing/SwingLuan.java src/luan/modules/swing/UndoManagerLuan.java
diffstat 6 files changed, 61 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/LuanFunction.java	Mon Apr 07 22:34:12 2025 -0600
+++ b/src/luan/LuanFunction.java	Tue Apr 08 13:40:37 2025 -0600
@@ -5,6 +5,10 @@
 
 	public abstract Object call(Luan luan,Object... args) throws LuanException;
 
+	public boolean canTake(int nArgs) {
+		return false;
+	}
+
 	public static final Object[] NOTHING = new Object[0];
 
 	@Override public String toString() {
--- a/src/luan/LuanJavaFunction.java	Mon Apr 07 22:34:12 2025 -0600
+++ b/src/luan/LuanJavaFunction.java	Tue Apr 08 13:40:37 2025 -0600
@@ -20,6 +20,7 @@
 	private final boolean takesLuan;
 	private final ArgConverter[] argConverters;
 	private final Class varArgCls;
+	private final int nArgs;
 
 	public LuanJavaFunction(Method method,Object obj) {
 		this( JavaMethod.of(method), obj );
@@ -37,8 +38,10 @@
 		if( method.isVarArgs() ) {
 			Class[] paramTypes = method.getParameterTypes();
 			this.varArgCls = paramTypes[paramTypes.length-1].getComponentType();
+			this.nArgs = -1;  // not used
 		} else {
 			this.varArgCls = null;
+			this.nArgs = this.argConverters.length;
 		}
 		this.obj = obj;
 	}
@@ -49,9 +52,14 @@
 		this.takesLuan = fn.takesLuan;
 		this.argConverters = fn.argConverters;
 		this.varArgCls = fn.varArgCls;
+		this.nArgs = fn.nArgs;
 		this.obj = obj;
 	}
 
+	@Override public boolean canTake(int nArgs) {
+		return nArgs <= this.nArgs || method.isVarArgs();
+	}
+
 	@Override public String toString() {
 		return "java-function: " + method;
 	}
--- a/src/luan/impl/LuanParser.java	Mon Apr 07 22:34:12 2025 -0600
+++ b/src/luan/impl/LuanParser.java	Tue Apr 08 13:40:37 2025 -0600
@@ -259,9 +259,9 @@
 		return t;
 	}
 
-	private Expr newFnExp(Stmts stmt,String name) {
+	private Expr newFnExp(Stmts stmt,String name,int nArgs) {
 		String className = "INNER" + ++innerCounter;
-		Inner inner = new Inner( stmt, name, className );
+		Inner inner = new Inner( stmt, name, className, nArgs );
 		inners.add(inner);
 		return inner.toInnerFnExp( frame.upValueSymbols );
 //		return toFnExp( stmt, frame.upValueSymbols, name );
@@ -1144,7 +1144,7 @@
 		stmt.add( "}  " );
 		stmt.add( "return lsw.out().toString();  " );
 		stmt.hasReturn = true;
-		Expr fnDef = newFnExp(stmt,null);
+		Expr fnDef = newFnExp(stmt,null,0);
 		Expr exp = new Expr(Val.SINGLE,true);
 		exp.addAll( fnDef );
 		exp.add( ".call(luan)" );
@@ -1166,13 +1166,14 @@
 		frame = new Frame(frame);
 		Stmts stmt = new Stmts();
 		List<String> names = NameList();
+		int n = -1;
 		if( names != null ) {
 /*
 			Expr args = new Expr(Val.ARRAY,false);
 			args.add( "args" );
 			stmt.addAll( makeLocalSetStmt(names,args) );
 */
-			int n = names.size();
+			n = names.size();
 			Expr t = new Expr(Val.SINGLE,false);
 			for( int i=0; i<n; i++ ) {
 				t.clear();
@@ -1195,6 +1196,7 @@
 			frame.isVarArg = true;
 			stmt.add( "final Object[] varArgs = LuanImpl.varArgs(args,0);  " );
 		} else {
+			n = 0;
 			stmt.add( "LuanImpl.noMore(args,0);  " );
 		}
 		RequiredMatch(')');
@@ -1202,7 +1204,8 @@
 		Stmts block = RequiredBlock();
 		stmt.addAll( block );
 		stmt.hasReturn = block.hasReturn;
-		Expr fnDef = newFnExp(stmt,name);
+		int nArgs = frame.isVarArg ? -1 : n;
+		Expr fnDef = newFnExp(stmt,name,nArgs);
 		if( !Keyword("end") && !Keyword("end_function") ) {
 			if( stmt.hasReturn && !parser.endOfInput() ) {
 				throw parser.exception("unreachable statement");
@@ -2089,8 +2092,9 @@
 		private final String className;
 		private final int lines;
 		private final int endLine;
+		private final int nArgs;
 
-		Inner(Stmts stmts,String name,String className) {
+		Inner(Stmts stmts,String name,String className,int nArgs) {
 			this.stmts = stmts;
 			this.name = name;
 			this.className = className;
@@ -2100,6 +2104,7 @@
 				stmts.add( "return LuanFunction.NOTHING;  " );
 			this.lines = lines( stmts.toString() );
 			this.endLine = lines( parser.textFrom(0) );
+			this.nArgs = nArgs;
 		}
 
 		Expr toInnerFnExp(List<UpSym> upValueSymbols) {
@@ -2124,6 +2129,7 @@
 			StringBuilder sb = new StringBuilder();
 			sb.append( ""
 				+"private static class " + className +" extends LuanClosure {  "
+					+"private final int nArgs = "+nArgs+"; "
 					+className+"(Pointer[] upValues,boolean javaOk,String sourceName) throws LuanException {  "
 						+"super(upValues,javaOk,sourceName);  "
 					+"}  "
@@ -2136,6 +2142,9 @@
 						+"Object[] a;  "
 						+ stmts
 					+"}  "
+					+"@Override public boolean canTake(int nArgs) { "
+						+"return this.nArgs == -1 || nArgs <= this.nArgs; "
+					+"}  "
 				+"}  "
 			);
 			return sb.toString();
--- a/src/luan/modules/swing/Document.luan	Mon Apr 07 22:34:12 2025 -0600
+++ b/src/luan/modules/swing/Document.luan	Tue Apr 08 13:40:37 2025 -0600
@@ -20,6 +20,7 @@
 	document.add_undo_listener = undo.addListener
 	document.is_unedited = undo.isUnedited
 	document.set_unedited = undo.setUnedited
+	document.clear_unedited = undo.clearUnedited
 	return document
 end
 
--- a/src/luan/modules/swing/SwingLuan.java	Mon Apr 07 22:34:12 2025 -0600
+++ b/src/luan/modules/swing/SwingLuan.java	Tue Apr 08 13:40:37 2025 -0600
@@ -5,6 +5,7 @@
 import javax.swing.KeyStroke;
 import javax.swing.Action;
 import javax.swing.AbstractAction;
+import javax.swing.JComponent;
 import javax.swing.UnsupportedLookAndFeelException;
 import javax.swing.text.JTextComponent;
 import javax.swing.text.Document;
@@ -16,7 +17,7 @@
 import java.awt.event.WindowAdapter;
 import luan.Luan;
 import luan.LuanFunction;
-//import luan.LuanMutable;
+import luan.LuanTable;
 import luan.LuanException;
 import luan.LuanRuntimeException;
 
@@ -60,20 +61,37 @@
 		SwingUtilities.invokeLater(runnable(luan,fn));
 	}
 
-	public static ActionListener newActionListener(final Luan luan,LuanFunction fn) {
+	private static void exception(LuanException e) {
+		System.err.println(e.getLuanStackTraceString());
+		System.exit(1);
+	}
+
+	private static void exception(String msg) {
+		exception( new LuanException(msg) );
+	}
+
+	public static ActionListener newActionListener(final Luan luan,final LuanFunction fn) throws LuanException {
 		if( fn == null )
-			throw new NullPointerException("function is null");
+			exception("function is null");
+		if( !fn.canTake(1) )
+			exception("action listener function must take event parameter");
 		return new ActionListener() {
-			private void call() {
+			@Override public void actionPerformed(ActionEvent event) {
 				try {
-					fn.call(luan);
+					LuanTable t = new LuanTable();
+					Object source = event.getSource();
+					if( source instanceof JComponent ) {
+						JComponent jcomponent = (JComponent)source;
+						Object component = jcomponent.getClientProperty("luan");
+						if( component != null )
+							t.rawPut("source",component);
+					}
+					fn.call(luan,t);
 				} catch(LuanException e) {
-					throw new LuanRuntimeException(e);
+					//throw new LuanRuntimeException(e);
+					exception(e);
 				}
 			}
-			@Override public void actionPerformed(ActionEvent e) {
-				call();
-			}
 		};
 	}
 
--- a/src/luan/modules/swing/UndoManagerLuan.java	Mon Apr 07 22:34:12 2025 -0600
+++ b/src/luan/modules/swing/UndoManagerLuan.java	Tue Apr 08 13:40:37 2025 -0600
@@ -64,4 +64,10 @@
 		unedited = editToBeUndone();
 		notifyListeners();
 	}
+
+	public void clearUnedited() {
+		discardAllEdits();
+		unedited = null;
+		notifyListeners();
+	}
 }